nyoj-677-最大流最小割

677-碟战


内存限制:64MB 时间限制:2000ms 特判: No
通过数:2 提交数:2 难度:4

题目描述:

知己知彼,百战不殆!在战争中如果被敌人掌握了自己的机密,失败是必然的。K国在一场战争中屡屡失败,就想到自己的某些城市可能会有敌方的间谍。

在仔细调查后,终于得知在哪些城市存在间谍。当然这个消息也被敌方间谍得知,所以间谍们开始撤离,试图到达K国唯一机场,然后抢夺飞机回国。由于城市内部比较复杂,K国领导人决定封锁道路,阻止所有间谍到达机场。城市编号为1~N,两个城市有不超过1条双向道路相连。机场在N号城市,不会有间碟。

由于要节约兵力,至少要封锁多少条道路才能阻止所有间谍到达机场?

输入描述:

第一行包含一个整数T(T <= 100),为测试数据组数。
接下来每组测试数据第一行包含三个整数n,m,p(2<= n <= 200,1< m < 20000,1 <= p < n),分别表示城市数量,道路数量,存在间谍的城市的数量。
接下来的一行包含p个整数x(1 <= x < n),表示存在间谍城市的编号。
接下来的m行,每行包含两个整数i,j,表示城市i与城市j有道路相通。

输出描述:

输出“Case #i: ans”(不含引号),i为第i组数据,ans为需要封锁道路的条数。

样例输入:

2
4 4 2
1 2
1 2
2 4
1 3
3 4
4 3 2
1 2
2 3
3 4
2 4

样例输出:

Case #1: 2
Case #2: 2

  由最大流最小割定理可知我们求出最大流就是答案。建立一个源点S,向所有有间谍的点连边,容量为
inf(因为不确定这个点有几条路能到终点),然后加上题目中给的边,容量是1,然后跑到N点的最大流
就是答案。
  所有间谍点都到不了终点<==>从S点出发到不了终点<==>求S-T最大流
  
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define inf 0x3f3f3f3f
 4 int flow[220][220],d[220],N;
 5 bool vis[220];
 6 bool bfs(){
 7   queue<int>q;
 8   q.push(N);
 9   d[N]=0;
10   memset(vis,0,sizeof(vis));
11   vis[N]=1;
12   while(!q.empty()){
13     int u=q.front();q.pop();
14     for(int i=1;i<=N;++i){
15       if(!vis[i] && flow[u][i]){
16         vis[i]=1;
17         d[i]=d[u]+1;
18         q.push(i);
19       }
20     }
21   }
22   return vis[N-1];
23 }
24 int dfs(int u,int a){
25   if(u==N-1 ||a==0) return a;
26   int f,ans=0;
27   for(int i=1;i<=N;++i){
28     if(d[i]==d[u]+1 && (f=dfs(i,min(a,flow[u][i])))>0){
29       flow[u][i]-=f;
30       flow[i][u]+=f;
31       ans+=f;
32       a-=f;
33       if(!a) break;
34     }
35   }
36   return ans;
37 }
38 int solve(){
39   int ans=0;
40   while(bfs()){
41     ans+=dfs(N,inf);
42   }
43   return ans;
44 }
45 int main(){
46   int t,i,j,k,u,v,m,p;
47   cin>>t;
48   for(int cas=1;cas<=t;++cas){
49     memset(flow,0,sizeof(flow));
50     cin>>N>>m>>p,++N;
51     for(i=1;i<=p;++i){
52       scanf("%d",&u);
53       flow[N][u]=inf;
54     }
55     while(m--){
56       scanf("%d%d",&u,&v);
57       flow[u][v]++;
58       flow[v][u]++;
59     }
60     printf("Case #%d: %d
",cas,solve());
61   }
62   return 0;
63 }

原文地址:https://www.cnblogs.com/zzqc/p/9396387.html