hdu 4289 dinic模板
题意:有N个城市,现在城市S出现了一伙歹徒,他们想运送一些炸弹到D城市,不过警方已经得到了线报知道他们的事情,不过警察不知道他们所在的具体位置,所以只能采取封锁城市的办法来阻断暴徒,不过封锁城市是需要花费一定代价的,由于警局资金比较紧张,所以想知道如果完全阻断暴徒从S城市到达D城市的最小需要花费的代价。
思路:将每个点都拆分成2个,表示为i和i*,i是原来的起点,然后i到i*的权值为i点原来的权值,连边的时候要注意的是要从i*连接i,因为最初在起点的时候,首先要走的就是从i到i*,然后接下来一定是从i*出发回到i这一边,假设是j,然后j走j*,这样循环往复,所以边的方向都应该是i*到i。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<string.h> 3 #include<algorithm> 4 #include<math.h> 5 #include<queue> 6 using namespace std; 7 const int maxn=1000; 8 const int inf=0x3f3f3f3f; 9 int head[maxn],level[maxn]; 10 int vis[maxn]; 11 int num; 12 void init() 13 { 14 num=-1 ; 15 memset(head,-1,sizeof(head)); 16 } 17 struct node 18 { 19 int v,w,next; 20 }G[400000]; 21 int bfs(int s,int t) 22 { 23 queue<int>q; 24 q.push(s); 25 memset(level,-1,sizeof(level)); 26 level[s]=0; 27 while(!q.empty()){ 28 int u=q.front(); 29 q.pop(); 30 for(int i=head[u];i!=-1;i=G[i].next){ 31 int v=G[i].v; 32 if(G[i].w>0&&level[v]==-1){ 33 level[v]=level[u]+1; 34 q.push(v); 35 } 36 } 37 } 38 return level[t]; 39 } 40 int dfs(int s,int t,int f) 41 { 42 if(s==t) return f; 43 int ans=0; 44 for(int i=vis[s];i!=-1;i=G[i].next){ 45 vis[s]=i; //当前弧优化 46 int v=G[i].v; 47 if(G[i].w>0&&level[s]+1==level[v]){ 48 int d=dfs(v,t,min(G[i].w,f-ans)); 49 if(d>0){ 50 G[i].w-=d; 51 G[i^1].w+=d; 52 ans+=d; 53 if(ans==f) return ans; 54 } 55 } 56 } 57 return ans; 58 } 59 int dinic(int s,int t) 60 { 61 int ans=0; 62 while(1){ 63 int temp=bfs(s,t); 64 if(temp==-1) break; 65 memcpy(vis,head,sizeof(vis)); 66 ans+=dfs(s,t,inf); 67 } 68 return ans; 69 } 70 void build(int u,int v,int w) 71 { 72 num++;G[num].v=v;G[num].w=w;G[num].next=head[u];head[u]=num; 73 num++;G[num].v=u;G[num].w=0;G[num].next=head[v];head[v]=num; 74 } 75 int main() 76 { 77 int n,m; 78 while(scanf("%d%d",&n,&m)!=EOF){ 79 init(); 80 int s,t; 81 scanf("%d%d",&s,&t); 82 t=t+n; 83 int temp; 84 for(int i=1;i<=n;i++){ 85 scanf("%d",&temp); 86 build(i,i+n,temp); 87 } 88 for(int i=1;i<=m;i++){ 89 int u;int v; 90 scanf("%d%d",&u,&v); 91 build(u+n,v,inf); 92 build(v+n,u,inf); 93 } 94 printf("%d\n",dinic(s,t)); 95 } 96 return 0; 97 }