bzoj 1585: [Usaco2009 Mar]Earthquake Damage 2 地震伤害

Description

Farmer John的农场里有P个牧场,有C条无向道路连接着他们,第i条道路连接着两个牧场Ai和Bi,注意可能有很多条道路连接着相同的Ai和Bi,并且Ai有可能和Bi相等。Farmer John在1号牧场里。由于地震,某些牧场被损坏,但由于信春哥,C条道路没有一条损坏。有N头奶牛,他们在不同的牧场里,于是N <= P。他们一一向Farmer John报告。第i头奶牛报告给Farmer John一个整数Report_i,代表第Report_i个牧场没有损毁,但不能够从第Report_i个牧场经过一些没有损坏的牧场到达1号牧场。现在Farmer John想知道,最少有多少损坏的牧场。

Input

第一行三个整数 P,C,N

第2..C+1行:每行两个整数Ai,Bi

第C+2..C+N+1行:第C+1+i行包含一个整数,Report_i

Output

一个整数,代表最少有多少损坏的牧场

Sample Input

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

Sample Output

1
【数据规模】
1 <= P <=3000
1 <= C <=20000

HINT

本题是最小割,根据最大流来求。 

裂点法,第i个点列成2*i-1和2*i

如果第i个点一定不能被损坏,那么2i-1到2*i的容量就是无穷大,否则容量就是1. 

 1 #include<bits/stdc++.h>
 2 using namespace std;  
 3 int const N=3000+10;  
 4 int const M=20000+10;  
 5 int const inf=1e6; 
 6 struct edge{
 7     int to,nt,cp,fl;  
 8 }e[M<<3];  
 9 int s,t,n,m,k,h[N<<1],cnt,x[M],y[M],vis[N],dist[N<<1],q[N<<1],w[N<<1];  
10 void add(int a,int b,int c){
11     e[cnt].to=b; e[cnt].cp=c; e[cnt].fl=0;  e[cnt].nt=h[a]; h[a]=cnt++;  
12     e[cnt].to=a; e[cnt].cp=0; e[cnt].fl=0;  e[cnt].nt=h[b]; h[b]=cnt++;  
13 }
14 int dinic_bfs(){
15     memset(dist,-1,sizeof(dist));  
16     int cl=0; q[cl++]=s; dist[s]=0;  
17     for(int i=0;i<cl;i++){
18         int x=q[i];  
19         for(int j=h[x];j!=-1;j=e[j].nt){
20             int v=e[j].to;  
21             if(e[j].cp>e[j].fl && dist[v]==-1){
22                 dist[v]=dist[x]+1;  
23                 q[cl++]=v;  
24             }
25         }
26     }
27     return dist[t]>=0;  
28 }
29 int dinic_dfs(int x,int flow){
30     if(x==t) return flow;  
31     for(int &i=w[x];i!=-1;i=e[i].nt){
32         int v=e[i].to,tmp=0;  
33         if(e[i].cp>e[i].fl && dist[v]==dist[x]+1 &&  (tmp=dinic_dfs(v,min(flow,e[i].cp-e[i].fl)))){
34             e[i].fl+=tmp;  
35             e[i^1].fl-=tmp; 
36             return tmp; 
37         }
38     }
39     return 0;  
40 }
41 int main(){
42     scanf("%d%d%d",&n,&m,&k);  
43     for(int i=1;i<=m;i++)  
44         scanf("%d%d",&x[i],&y[i]);  
45     while (k--){
46         int v; 
47         scanf("%d",&v);  
48         vis[v]=1;  
49     }
50     memset(h,-1,sizeof(h));  
51     for(int i=1;i<=n;i++)  
52         if(!vis[i] && i!=1){
53             add(2*i-1,2*i,1);  
54         } else  add(2*i-1,2*i,inf);   
55     s=1;  
56     t=2*n+1; 
57     for(int i=1;i<=n;i++)  
58         if(vis[i]) add(2*i-1,t,inf); 
59     for(int i=1;i<=m;i++){
60         add(2*x[i],2*y[i]-1,inf);  
61         add(2*y[i],2*x[i]-1,inf);  
62     }
63     int tmp,ans=0;  
64     while (dinic_bfs()){
65         memcpy(w,h,sizeof(h));  
66         while ((tmp=dinic_dfs(s,inf)))  
67             ans+=tmp;  
68     }
69     cout<<ans<<endl; 
70     return 0; 
71 }
View Code

 

posted @ 2019-08-21 15:42  zjxxcn  阅读(174)  评论(0编辑  收藏  举报