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。

 

 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 }
View Code

 

posted @ 2019-09-24 19:07  古比  阅读(146)  评论(0编辑  收藏  举报