HDU 3987 && DINIC

很容易发现是网络流的题目,但最少边怎么求呢?初时想不到,但画图后忽然发现可以这样:

求一次网络流最小割后,把满流的边置1,不满流的置INF。再求一次最大流即可。

为什么呢?

是否会存在一些边当前不满流,但有可能是最少边数最少割的边呢?否。因为按照DINIC的求法,每次都是增广容量最少的路,若当前不满流,则必定不是最小割的边,所以只需在满流的边,即可组成最小割的边寻找最少边就可以了。

  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 #include <algorithm>
  5 using namespace std;
  6 
  7 const int INF=0x3f3f3f3f;
  8 const int MAXN=1050;
  9 const int MAXM=400000;
 10 
 11 struct Node{
 12     int from,to,next;
 13     int cap;
 14 }edge[MAXM];
 15 int tol;
 16 
 17 int dep[MAXN];
 18 int head[MAXN];
 19 
 20 int n,m;
 21 void init(){
 22     tol=0;
 23     memset(head,-1,sizeof(head));
 24 }
 25 void addedge(int u,int v,int w){
 26     edge[tol].from=u;
 27     edge[tol].to=v; edge[tol].cap=w;  edge[tol].next=head[u];
 28     head[u]=tol++;
 29     edge[tol].from=v;
 30     edge[tol].to=u;
 31     edge[tol].cap=0;
 32     edge[tol].next=head[v];
 33     head[v]=tol++;
 34 }
 35 
 36 int BFS(int start,int end){
 37     int que[MAXN];
 38     int front,rear; front=rear=0;
 39     memset(dep,-1,sizeof(dep));
 40     que[rear++]=start;
 41     dep[start]=0;
 42     while(front!=rear)    {
 43         int u=que[front++];
 44         if(front==MAXN)front=0;
 45         for(int i= head[u];i!=-1; i=edge[i].next){
 46             int v=edge[i].to;
 47             if(edge[i].cap>0&& dep[v]==-1){
 48                 dep[v]=dep[u]+1;
 49                 que[rear++]=v;
 50                 if(rear>=MAXN) rear=0;
 51                 if(v==end)return 1;
 52             }
 53         }
 54     }
 55     return 0;
 56 }
 57 int dinic(int start,int end){
 58     int res=0;
 59     int top;
 60     int stack[MAXN];
 61     int cur[MAXN];
 62     while(BFS(start,end)){
 63         memcpy(cur,head, sizeof(head));
 64         int u=start;
 65         top=0;
 66         while(1){
 67             if(u==end){
 68                 int min=INF;
 69                 int loc;
 70                for(int i=0;i<top;i++)
 71                   if(min>edge [stack[i]].cap) {
 72                       min=edge [stack[i]].cap;
 73                       loc=i;
 74                   }
 75                 for(int i=0;i<top;i++){
 76                     edge[stack[i]].cap-=min;
 77                     edge[stack[i]^1].cap+=min;
 78                 }
 79                 res+=min;         
 80                 top=loc;               
 81                 u=edge[stack[top]].from;
 82             }
 83             for(int i=cur[u]; i!=-1; cur[u]=i=edge[i].next)
 84               if(edge[i].cap!=0 && dep[u]+1==dep[edge[i].to])
 85                  break;
 86             if(cur[u] !=-1){
 87                 stack [top++]= cur[u];
 88                 u=edge[cur[u]].to;
 89             }
 90             else{
 91                 if(top==0) break;
 92                 dep[u]=-1;
 93                 u= edge[stack [--top] ].from;
 94             }
 95         }
 96     }
 97     return res;
 98 }
 99 
100 int main(){
101     int T,cas=0;
102     int u,v,w,d;
103     scanf("%d",&T);
104     while(T--){
105         init();
106         cas++;
107         scanf("%d%d",&n,&m);
108         for(int i=0;i<m;i++){
109             scanf("%d%d%d%d",&u,&v,&w,&d);
110             if(d){
111                 addedge(v,u,w);
112             }
113             addedge(u,v,w);
114         }
115         dinic(0,n-1);
116         for(int i=0;i<tol;i+=2){
117             if(edge[i].cap==0){
118                 edge[i].cap=1; edge[i^1].cap=0;
119             }
120             else {
121                 edge[i].cap=INF;
122                 edge[i^1].cap=0;
123             }
124         }
125         int ans=dinic(0,n-1);
126         printf("Case %d: ",cas);
127         printf("%d\n",ans);
128     }
129     return 0;
130 }
View Code

DINIC的模板

 1 const int INF=0x3f3f3f3f;
 2 const int MAXN=1050;
 3 const int MAXM=400000;
 4 
 5 struct Node{
 6     int from,to,next;
 7     int cap;
 8 }edge[MAXM];
 9 int tol;
10 
11 int dep[MAXN];
12 int head[MAXN];
13 
14 int n,m;
15 void init(){
16     tol=0;
17     memset(head,-1,sizeof(head));
18 }
19 void addedge(int u,int v,int w){
20     edge[tol].from=u;
21     edge[tol].to=v; edge[tol].cap=w;  edge[tol].next=head[u];
22     head[u]=tol++;
23     edge[tol].from=v;
24     edge[tol].to=u;
25     edge[tol].cap=0;
26     edge[tol].next=head[v];
27     head[v]=tol++;
28 }
29 
30 int BFS(int start,int end){
31     int que[MAXN];
32     int front,rear; front=rear=0;
33     memset(dep,-1,sizeof(dep));
34     que[rear++]=start;
35     dep[start]=0;
36     while(front!=rear)    {
37         int u=que[front++];
38         if(front==MAXN)front=0;
39         for(int i= head[u];i!=-1; i=edge[i].next){
40             int v=edge[i].to;
41             if(edge[i].cap>0&& dep[v]==-1){
42                 dep[v]=dep[u]+1;
43                 que[rear++]=v;
44                 if(rear>=MAXN) rear=0;
45                 if(v==end)return 1;
46             }
47         }
48     }
49     return 0;
50 }
51 int dinic(int start,int end){
52     int res=0;
53     int top;
54     int stack[MAXN];
55     int cur[MAXN];
56     while(BFS(start,end)){
57         memcpy(cur,head, sizeof(head));
58         int u=start;
59         top=0;
60         while(1){
61             if(u==end){
62                 int min=INF;
63                 int loc;
64                for(int i=0;i<top;i++)
65                   if(min>edge [stack[i]].cap) {
66                       min=edge [stack[i]].cap;
67                       loc=i;
68                   }
69                 for(int i=0;i<top;i++){
70                     edge[stack[i]].cap-=min;
71                     edge[stack[i]^1].cap+=min;
72                 }
73                 res+=min;         
74                 top=loc;               
75                 u=edge[stack[top]].from;
76             }
77             for(int i=cur[u]; i!=-1; cur[u]=i=edge[i].next)
78               if(edge[i].cap!=0 && dep[u]+1==dep[edge[i].to])
79                  break;
80             if(cur[u] !=-1){
81                 stack [top++]= cur[u];
82                 u=edge[cur[u]].to;
83             }
84             else{
85                 if(top==0) break;
86                 dep[u]=-1;
87                 u= edge[stack [--top] ].from;
88             }
89         }
90     }
91     return res;
92 }
View Code
posted @ 2014-07-22 10:57  chenjunjie1994  阅读(232)  评论(0编辑  收藏  举报