poj 1149

 

  

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <queue>
  4 #define _clr(x, y) memset(x, y, sizeof(x))
  5 #define Min(x, y) (x < y ? x : y)
  6 #define INF 0x3f3f3f3f
  7 #define N 150
  8 #define M 1005
  9 using namespace std;
 10 
 11 int resi[N][N], h[N], ef[N];
 12 int dist[N], pre[N];
 13 int Maxf, S, T;
 14 bool used[N];
 15 queue<int> Q;
 16 
 17 //  一般预流推进算法 --47ms
 18 void Push(int x)
 19 {
 20     for(int i=0; i<=T; i++)
 21     {
 22         int tmp = Min(ef[x], resi[x][i]);
 23         if(tmp>0 && (x==S || h[x]==h[i]+1))
 24         {
 25             resi[x][i] -= tmp, resi[i][x] += tmp;
 26             ef[x] -= tmp, ef[i] += tmp;
 27             if(i==T) Maxf += tmp;
 28             if(i!=S && i!=T) Q.push(i);
 29         }
 30     }
 31 }
 32 
 33 void Push_Relabel(int n)
 34 {
 35     Maxf = 0;
 36     _clr(ef, 0);
 37     _clr(h, 0);
 38     h[S] = n, ef[S]=INF, ef[T]=-INF;
 39     Q.push(S);
 40     while(!Q.empty())
 41     {
 42         int x = Q.front();
 43         Q.pop();
 44         Push(x);
 45         if(x!=S && x!=T && ef[x]>0)
 46         {
 47             h[x]++;
 48             Q.push(x);
 49         }
 50     }
 51     printf("%d\n",Maxf);
 52 }
 53 
 54 void Init(int m, int n)
 55 {   
 56     int pig[M], last[M];
 57     int num, k;
 58     S=0, T=n+1;
 59     _clr(last, 0);
 60     _clr(resi, 0);
 61     for(int i=1; i<=m; i++)
 62        scanf("%d", pig+i);
 63     for(int i=1; i<=n; i++)
 64     {
 65         scanf("%d", &num);
 66         for(int j=0; j<num; j++)
 67         {
 68             scanf("%d", &k);
 69             if(last[k]==0)
 70                 resi[S][i] += pig[k];
 71             else
 72                 resi[last[k]][i] = INF;
 73             last[k] = i;
 74         }
 75         scanf("%d", resi[i]+T);
 76     }
 77 }
 78 
 79 // 连续最短曾广路算法  --17ms
 80 bool bfs_dinic()
 81 {
 82     _clr(dist, -1);
 83     dist[S] = 0;
 84     Q.push(S);
 85     while(!Q.empty())
 86     {
 87         int u = Q.front();
 88         Q.pop();
 89         for(int i=0; i<=T; i++)
 90         {
 91             if(dist[i]<0 && resi[u][i])
 92             {
 93                 dist[i] = dist[u]+1;
 94                 Q.push(i);
 95             }
 96         }
 97     }
 98     return dist[T]>0 ? 1 : 0;
 99 }
100 
101 int dfs(int x, int f)
102 {
103     int a=0;
104     if(x==T) return f;
105     for(int i=0; i<=T; i++)
106     {
107         if(resi[x][i] && dist[i]==dist[x]+1 && (a=dfs(i, Min(f, resi[x][i]))))
108         {
109             resi[x][i] -= a, resi[i][x] += a;
110             return a;
111         }
112     }
113     return 0;
114 }
115 
116 void Dinic()
117 {
118     int ans=0, a;
119     while(bfs_dinic())
120         while(a=dfs(0, INF)) ans+= a;
121     printf("%d\n", ans);
122 }
123 
124 //  EK算法   --0ms
125 bool bfs()
126 {
127     _clr(used, 0);
128     _clr(pre, -1);
129     int Sta[N], top=0;
130     used[S] = true;
131     Sta[top++] = S;
132     while(top)
133     {
134         int u = Sta[--top];
135         for(int i=0; i<=T; i++)
136         {
137             if(resi[u][i] && !used[i])
138             {
139                 used[i] = true;
140                 pre[i] = u;
141                 if(i==T) return true;
142                 Sta[top++] = i;
143             }
144         }
145     }
146     return false;
147 }
148 void EK()
149 {
150     int maxf=0, d;
151     while(bfs())
152     {
153         d = INF;
154         for(int i=T; i!=S; i=pre[i])
155             d = Min(d, resi[pre[i]][i]);
156         for(int i=T; i!=S; i=pre[i])
157         {
158             resi[pre[i]][i] -= d;
159             resi[i][pre[i]] += d;
160         }
161         maxf += d;
162     }
163     printf("%d\n", maxf);
164 }
165 int main()
166 {
167     int n, m;
168     while(~scanf("%d%d", &m, &n))
169     {
170         while(!Q.empty()) Q.pop();
171         Init(m, n);
172         EK();
173         //Push_Relabel(n);
174         //Dinic();
175     }
176     return 0;
177 }

 

posted @ 2015-03-03 17:16  无道圣君  阅读(152)  评论(0编辑  收藏  举报