标签:acm codeforces 最大流
题目链接:click here~~
【题目大意】:给定一些城市里面原先状态的士兵数目,和某些城市之间的联通关系,求能否达到最终状态。
【解题思路】做完这套题,感觉这道题是五个题里最有质量的题了,搞了差不多一天半的时间,开始很难想到构图,想到了是最大流之后,又卡在了输出流量上,w(?Д?)w,还是这类题做的太少,~~~~(>_<)~~~~!首先比较很难构想到最大流,但是抓住题目关键,仔细想想也不难,好,想到了是构造最大流,那么接下来难点是建源点,汇点,剩下的就是套模板了,弱弱的献上代码,欢迎各位指正~~
Sample Input
4 4 1 2 6 3 3 5 3 1 1 2 2 3 3 4 4 2
YES 1 0 0 0 2 0 0 0 0 5 1 0 0 0 2 1
2 0 1 2 2 1
NO
代码:
/*
Author :HRW
思路:建图,最大流,注意反向边,容量,流量为0
建源点,汇点,
最后输出路径保证每条边的流量都要输出,只需之前统计有哪些边流量发生了变化
*/
#include <bits/stdc++.h>
using namespace std;
const int N=305;
const int inf=0x3f3f3f3f;
struct Edge
{
int from,to,cap,flow;//顶点-顶点,容量,流量
Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f) {}
};
vector <Edge> edges;
vector <int > G[N];
int d[N],cur[N],num[N][N];
int n,m,S,T,a,b,C;
bool vis[N],flag;
void init()
{
for(int i=0; i<=n; i++)
{
G[i].clear(),edges.clear();
}
}
void add_edge(int from,int to,int cap)
{
edges.push_back(Edge(from,to,cap,0));
edges.push_back(Edge(to,from,0,0));
C=edges.size();
G[from].push_back(C-2);
G[to].push_back(C-1);
}
bool bfs(int s,int t)
{
memset(vis,false,sizeof(vis));
queue <int >Q;
d[s]=0;
Q.push(s);
vis[s]=true;
while(!Q.empty())
{
int q=Q.front();
Q.pop();
for(int i=0; i<G[q].size(); i++)//一定要注意G[q].size(),写成G[i].size(),样例竟然过,导致RE一页!
{
Edge &e=edges[G[q][i]];
if(!vis[e.to]&&e.cap>e.flow)
{
d[e.to]=d[q]+1;
Q.push(e.to);
vis[e.to]=true;
}
}
}
return vis[T];
}
int dfs(int s,int k)
{
if(s==T||k==0) return k;
int f,flow=0;
for(int &i=cur[s]; i<G[s].size(); i++)
{
Edge &e=edges[G[s][i]];
if(d[e.to]==d[s]+1&&(f=dfs(e.to,min(k,e.cap-e.flow)))>0)
{
e.flow+=f;
edges[G[s][i]^1].flow-=f;
flow+=f;
k-=f;
if(k==0) break;
}
}
return flow;
}
int max_flow(int s,int t)
{
int flow=0;
while(bfs(s,t))
{
memset(cur,0,sizeof(cur));
flow+=dfs(s,inf);
}
return flow;
}
int main()
{
init();
scanf("%d%d",&n,&m);
S=0,T=2*n+1;
int u,v,a,b,suma=0,sumb=0;
for(int i=1; i<=n; i++)
{
scanf("%d",&a);
suma+=a;
add_edge(S,i,a);
add_edge(i,i+n,inf);
}
for(int i=1; i<=n; i++)
{
scanf("%d",&b);
sumb+=b;
add_edge(i+n,T,b);
}
if(suma!=sumb)
{
puts("NO");
return 0;
}
while(m--)
{
scanf("%d%d",&v,&u);
add_edge(v,u+n,inf);
add_edge(u,v+n,inf);
}
int ans=max_flow(S,T);
//cout<<ans<<endl;
if(suma!=ans)
{
puts("NO");
}
else
{
puts("YES");
for(int i=1; i<=n; i++)
{
for(int j=0; j<G[i].size(); j++)
{
Edge&e=edges[G[i][j]];
if(e.to>0) num[i][e.to-n]=e.flow;
}
}
for(int i=1; i<=n; i++)
{
for(int j=1; j<=n; j++)
printf("%d ",num[i][j]);
puts("");
}
}
return 0;
}
/*
4 4
1 2 6 3
3 5 3 1
1 2
2 3
3 4
4 2
*/CodeForces 546E - Soldier and Traveling(最大流+输出边流量)
标签:acm codeforces 最大流
原文地址:http://blog.csdn.net/u013050857/article/details/46137527