zoukankan      html  css  js  c++  java
  • 控制公司 Controlling Companies

    (USACO)(CHAPTER 2)

    的题

    黄题难度 但我写了一个网络流

    看了下题解 只有我是写的网络流

    其他好像都是搜索

    思想

    网络流中进行是否可以増广和増广是

    即(我写的(dinic))DINIC中的(BFS)(DFS)

    判断是否可以走的时候 改成

    if(depth[v = edge[e].v] == -1&&(edge[e].w&&able[tp]))//BFS
    if(depth[v = edge[e].v] == depth[x] + 1&&(edge[e].w&&able[x]))//DFS
    

    就行了 还有一些要注意的点 各位神仙写的时候很容易想到

    对了 我用了(set)优化

    可去重 可排序 为什么不用呢?

    时间复杂度

    (O(min(N^{0.67},M^{0.5}) * M*N^2))

    时间复杂度不比搜索优秀 但练练网络流也挺好的

    #include <set>
    #include <queue>
    #include <cstdio>
    #include <vector>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    #define reg register int
    #define isdigit(x) ('0' <= x&&x <= '9')
    template<typename T>
    inline T Read(T Type)
    {
    	T x = 0,f = 1;
    	char a = getchar();
    	while(!isdigit(a)) {if(a == '-') f = -1;a = getchar();}
    	while(isdigit(a)) {x = (x << 1) + (x << 3) + (a ^ '0');a = getchar();}
    	return x * f;
    }
    const int MAXN = 10000;
    int n,cnt,ori_[MAXN];
    struct node
    {
    	int v,w,_nxt;
    }edge[MAXN],pos_[MAXN];
    inline void addedge(int u,int v,int w)
    {
    	edge[++cnt].v = v;
    	edge[cnt]._nxt = ori_[u];
    	edge[cnt].w = w;
    	ori_[u] = cnt;
    }
    inline void add(int u,int v,int w) {addedge(u,v,w),addedge(v,u,0);}
    set<int> pany;
    bool able[MAXN],pr[MAXN];
    namespace Dinitz
    {
        const int inf = 0x7f7f7f7f;
        int depth[MAXN],fire[MAXN];
        inline bool Bfs(int s,int t)
        {
            memset(depth,-1,sizeof(depth));
            queue<int> q;
            q.push(s),depth[s] = 0;
            while(!q.empty())
            {
                int v,tp = q.front();q.pop();
                for(reg e = ori_[tp];e;e = edge[e]._nxt)
                    if(depth[v = edge[e].v] == -1&&(edge[e].w&&able[tp]))
                    {
                    	depth[v] = depth[tp] + 1,q.push(v);
                    	if(edge[e].w >= 50) able[v] = 1;
    				}
            }
            return (depth[t] != -1);
        }
        inline int dfs(int x,int t,int _flow)
        {
            if(x == t) return _flow; int v,flow_ = 0;
    		for(reg e = fire[x];e;e = edge[e]._nxt)
            {
                fire[x] = e;
                if(depth[v = edge[e].v] == depth[x] + 1&&(edge[e].w&&able[x]))
                {
                	if(edge[e].w >= 50) able[v] = 1;
                    int flow = dfs(v,t,min(_flow,edge[e].w));
                    _flow -= flow,flow_ += flow;
                    edge[e].w -= flow,edge[e ^ 1].w += flow;
                    if(!_flow) break;
                }
            }
            if(!flow_) depth[x] = -1;
            return flow_;
        }
        inline int Dinic(int s,int t)
        {
            int ans = 0;
            while(Bfs(s,t))
            {
                for(set<int>::iterator i = pany.begin();i != pany.end();i++) fire[*i] = ori_[*i];
                ans += dfs(s,t,inf);
            }
            return ans;
        }
    }
    int main()
    {
    	cnt = 1,n = Read(1);
    	for(reg i = 1;i <= n;i++)
    	{
    		int u = Read(1),v = Read(1),w = Read(1);
    		add(u,v,w);
    		pany.insert(u),pany.insert(v);
    	}
    	for(reg i = 1;i <= cnt;i++) pos_[i] = edge[i];
    	for(set<int>::iterator i = pany.begin();i != pany.end();i++)
    	{
    		memset(able,0,sizeof(able));
    		memset(pr,0,sizeof(pr));
    		set<int> pr_;
    		able[*i] = 1;
    		int num = 1;
    		while(num)
    		{
    			num = 0;
    			for(set<int>::iterator j = pany.begin();j != pany.end();j++)
    			{
    				if(*i == *j||pr[*j]) continue;
    				int max_ = Dinitz::Dinic(*i,*j);
    				for(reg k = 1;k <= cnt;k++) edge[k] = pos_[k];
    				if(max_ >= 50) pr_.insert(*j),num++,pr[*j] = able[*j] = 1;
    			}
    		}
    		for(set<int>::iterator j = pr_.begin();j != pr_.end();j++) printf("%d %d
    ",*i,*j);
    	}
    	return 0;
    }
    
  • 相关阅读:
    TCP/IP、UDP、HTTP详解
    第一章 Shiro简介(学习笔记)
    [已失效]坦白说(查看好友)抓包教程+解密工具
    常用正则表达式
    计算机网络基础
    三层交换机配置实例
    计算机网络基础3
    计算机网络基础4
    计算机基础2
    Linux基础命令练习1
  • 原文地址:https://www.cnblogs.com/resftlmuttmotw/p/11949403.html
Copyright © 2011-2022 走看看