• Frequency Hopping UVA


    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define pb push_back
    const int maxn=2e5+7;
    const int inf=0x3f3f3f3f;
    
    int num_nodes,num_edges;
    int tot;
    int d[maxn],cur[maxn],source,sink;
    int p[maxn],num[maxn],vis[maxn];
    
    struct EDGE{
    	int from,to,cap,flow;
    };
    vector<EDGE>edge;
    vector<int>G[maxn];
    
    void init(){
    	edge.clear();
    	for(int i=0;i<maxn;i++)G[i].clear();
    }
    
    void addedge(int u,int v,int w){
    	edge.push_back((EDGE){u,v,w,0});
    	edge.push_back((EDGE){v,u,0,0});
    	tot=edge.size();
    	G[u].push_back(tot-2);
    	G[v].push_back(tot-1);
    }
    
    int bfs(){
    	memset(vis,0,sizeof vis);
    	queue<int>Q;
    	Q.push(sink);
    	vis[sink]=1;
    	d[sink]=0;
    	while(!Q.empty()){
    		int u=Q.front();
    		Q.pop();
    		int sz=G[u].size();
    		for(int i=0;i<sz;++i){
    			EDGE &e=edge[G[u][i]^1];
    			if(!vis[e.from] && e.cap>e.flow){
    				vis[e.from]=1;
    				d[e.from]=d[u]+1;
    				Q.push(e.from);
    			}
    		}
    	}
    	return vis[source];
    }
    
    int augment(){
    	int u=sink,a=inf;
    	while(u!=source){
    		EDGE &e=edge[p[u]];
    		a=min(a,e.cap-e.flow);
    		u=edge[p[u]].from;
    	}
    	u=sink;
    	while(u!=source){
    		edge[p[u]].flow+=a;
    		edge[p[u]^1].flow-=a;
    		u=edge[p[u]].from;
    	}
    	return a;
    }
    
    int maxflow(){
    	int flow=0;
    	bfs();
    	memset(num,0,sizeof num);
    	for(int i=0;i<=num_nodes;i++)num[d[i]]++;
    	int u=source;
    	memset(cur,0,sizeof cur);
    	while(d[source]<num_nodes){
    		if(u==sink){
    			flow+=augment();
    			u=source;
    		}
    		int advance=0;
    		int sz=G[u].size();
    		for(int i=cur[u];i<sz;i++){
    			EDGE &e=edge[G[u][i]];
    			if(e.cap>e.flow && d[u]==d[e.to]+1){
    				advance=1;
    				p[e.to]=G[u][i];
    				cur[u]=i;
    				u=e.to;
    				break;
    			}
    		}
    		if(!advance){
    			int m=num_nodes-1;
    			int sz=G[u].size();
    			for(int i=0;i<sz;i++){
    				if(edge[G[u][i]].cap>edge[G[u][i]].flow){
    					m=min(m,d[edge[G[u][i]].to]);
    				}			
    			}
    			if(--num[d[u]]==0)break;
    			num[d[u]=m+1]++;
    			cur[u]=0;
    			if(u!=source)u=edge[p[u]].from;
    		}
    	}
    	return flow;
    }
    
    vector<int>cut;
    void mincut(){
    	bfs();cut.clear();
    	int sz=edge.size();
    	for(int i=0;i<sz;i++){
    		EDGE &e=edge[i];
    		if(vis[e.to]&&!vis[e.from]&&e.cap>0)cut.pb(i);
    	}
    }
    void reduce(){	//上限缩减,不重复统计原始最大流
    	int sz=edge.size();
    	for(int i=0;i<sz;i++)edge[i].cap-=edge[i].flow;
    }
    void flowclear(){
    	int sz=edge.size();
    	for(int i=0;i<sz;i++)edge[i].flow=0;
    }
    
    int cmp(EDGE a,EDGE b){
    	if(a.from==b.from)return a.to<b.to;
    	else return a.from<b.from;
    }
    
    int main(){
    	int kase=0;int n,m,c;
    	while(scanf("%d%d%d",&n,&m,&c)&&n){
    		num_nodes=n;
    		source=1;sink=n;
    		init();
    		for(int i=1;i<=m;i++){
    			int u,v,w;scanf("%d%d%d",&u,&v,&w);
    			addedge(u,v,w);
    		}
    		printf("Case %d: ",++kase);
    		int maxFlow=maxflow();
    		if(maxFlow>=c||c==0)printf("possible
    ");
    		else{
    			vector<EDGE>ans;
    			mincut();
    			reduce();int sz=cut.size();
    
    			for(int i=0;i<sz;i++){
    				flowclear();
    				EDGE &e=edge[cut[i]];
    				e.cap+=c;
    				if(maxFlow+maxflow()>=c)ans.pb(edge[cut[i]]);
    				e.cap-=c;
    			}
    			if(ans.empty())printf("not possible
    ");
    			else{
    				sort(ans.begin(),ans.end(),cmp);
    				int sz=ans.size();
    				for(int i=0;i<sz;i++){		
    					if(i==0)printf("possible option:(%d,%d)",ans[i].from,ans[i].to);
    					else printf(",(%d,%d)",ans[i].from,ans[i].to);
    				}
    				printf("
    ");
    			}
    		}
    	}
    }
    
    

    要点在于reduce函数的上限缩减

    算是最小割的模板

  • 相关阅读:
    编译问题----宏定义一定显示未定义
    低级错误记录-程序更新后,没有显示想要的结果
    云编译的优点-普及云编译
    telecommunication communication 的区别
    学习EPC架构演进历史知识
    EOF与feof的区别
    epoll惊群问题-解决思路
    epoll多路复用机制的学习
    进程组与组长进程
    记录博客开始
  • 原文地址:https://www.cnblogs.com/Drenight/p/8611305.html
Copyright © 2020-2023  润新知