Frequency Hopping UVA

来源:互联网 发布:无法连接steam网络 编辑:程序博客网 时间:2024/06/07 03:46
#include<bits/stdc++.h>using namespace std;#define ll long long#define pb push_backconst 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\n");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\n");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("\n");}}}}

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

算是最小割的模板