HDU 3416 Marriage Match IV

http://acm.hdu.edu.cn/showproblem.php?pid=3416

题意:某狼要到别的城市去面基,但是去每个城市都要走最短路,每条路只能走一次。求最多的路径条数。

题解:先跑最短路把最短路处理出来。然后建网络流的边。

   建边:把能到达源点的边加入进去,容量为1。也可以求两遍最短路,把同时到达源点和汇点的路径加进去。但是只把能到达源点的加进去,即使这条边不到达汇点也不会影响结果。

  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 #include <cstdlib>
  5 #include <cmath>
  6 #include <string>
  7 #include <vector>
  8 #include <list>
  9 #include <map>
 10 #include <queue>
 11 #include <stack>
 12 #include <bitset>
 13 #include <algorithm>
 14 #include <numeric>
 15 #include <functional>
 16 #include <set>
 17 #include <fstream>
 18 
 19 using namespace std;
 20 
 21 const int INF=0x3f3f3f3f;
 22 const int maxm=10000010;
 23 const int maxn=1010;
 24 
 25 int N,M;
 26 struct edge{
 27     int u,v,cap,next;
 28 }G[maxm];
 29 int head[maxn*maxn],pre[maxn*maxn],level[maxn*maxn];
 30 int num[maxn*maxn],cur[maxn*maxn];
 31 int idx;
 32 int s,t,tt;
 33 struct edges{
 34     int v,w,next;
 35 }road[maxm];
 36 int head1[maxn*2],used[maxn*2],d[maxn*2];
 37 int idx1;
 38 
 39 void add_road(int u,int v,int w)
 40 {
 41     road[idx1].v=v;
 42     road[idx1].w=w;
 43     road[idx1].next=head1[u];
 44     head1[u]=idx1++;
 45 }
 46 
 47 void SPFA()
 48 {
 49     memset(d,INF,sizeof(d));
 50     memset(used,0,sizeof(used));
 51     queue<int> q;
 52     q.push(s);
 53     d[s]=0;
 54     while(!q.empty())
 55     {
 56         int u=q.front();
 57         q.pop();
 58         used[u]=0;
 59         for(int i=head1[u];i!=-1;i=road[i].next)
 60         {
 61             int v=road[i].v;
 62             if(d[v]>d[u]+road[i].w){
 63                 d[v]=d[u]+road[i].w;
 64                 if(!used[v]){
 65                     used[v]=1;
 66                     q.push(v);
 67                 }
 68             }
 69         }
 70     }
 71 }
 72 
 73 void build(int u,int v,int cap)
 74 {
 75     G[idx].v=v;
 76     G[idx].cap=cap;
 77     G[idx].next=head[u];
 78     head[u]=idx++;
 79 }
 80 
 81 void add_edge(int u,int v,int cap)
 82 {
 83     build(u,v,cap);
 84     build(v,u,0);
 85 }
 86 
 87 void bfs()
 88 {
 89     memset(level,-1,sizeof(level));
 90     memset(num,0,sizeof(num));
 91     queue<int> q;
 92     q.push(t);
 93     level[t]=0;
 94     num[0]=1;
 95     while(!q.empty())
 96     {
 97         int u=q.front();
 98         q.pop();
 99         for(int i=head[u];i!=-1;i=G[i].next)
100         {
101             int v=G[i].v;
102             if(level[v]==-1){
103                 level[v]=level[u]+1;
104                 num[level[v]]++;
105                 q.push(v);
106             }
107         }
108     }
109 }
110 
111 void ISAP()
112 {
113     memcpy(cur,head,sizeof(cur));
114     bfs();
115     int flow=0;
116     int u=pre[s]=s;
117     while(level[s]<tt)
118     {
119         if(u==t){
120             int f=INF,pos;
121             for(int i=s;i!=t;i=G[cur[i]].v)
122             {
123                 if(f>G[cur[i]].cap){
124                     f=G[cur[i]].cap;
125                     pos=i;
126                 }
127             }
128             for(int i=s;i!=t;i=G[cur[i]].v)
129             {
130                 G[cur[i]].cap-=f;
131                 G[cur[i]^1].cap+=f;
132             }
133             flow+=f;
134             u=pos;
135         }
136         int k;
137         for(k=cur[u];k!=-1;k=G[k].next)
138         {
139             if(level[G[k].v]+1==level[u]&&G[k].cap) break;
140         }
141         if(k!=-1){
142             cur[u]=k;
143             pre[G[k].v]=u;
144             u=G[k].v;
145         }else{
146             if(--num[level[u]]==0) break;
147             int mind=tt;
148             for(int i=head[u];i!=-1;i=G[i].next)
149             {
150                 if(mind>level[G[i].v]&&G[i].cap){
151                     mind=level[G[i].v];
152                     cur[u]=i;
153                 }
154             }
155             level[u]=mind+1;
156             num[level[u]]++;
157             u=pre[u];
158         }
159     }
160     printf("%d\n",flow);
161 }
162 
163 void build_graph()
164 {
165     for(int i=1;i<=N;i++)
166     {
167         for(int j=head1[i];j!=-1;j=road[j].next)
168         {
169             if(d[road[j].v]==d[i]+road[j].w){
170                 add_edge(i,road[j].v,1);
171             }
172         }
173     }
174 }
175 int main()
176 {
177 //    freopen("/Users/apple/Desktop/暑假/29(2)/29(2)/in","r",stdin);
178     int T;
179     scanf("%d",&T);
180     while(T--)
181     {
182         idx=0;
183         memset(head,-1,sizeof(head));
184         idx1=0;
185         memset(head1,-1,sizeof(head1));
186         scanf("%d%d",&N,&M);
187         tt=N+1;
188         for(int i=0;i<M;i++)
189         {
190             int u,v,w;
191             scanf("%d%d%d",&u,&v,&w);
192             if(u==v) continue;
193             else add_road(u, v, w);
194         }
195         scanf("%d%d",&s,&t);
196         SPFA();
197         build_graph();
198         ISAP();
199     }
200     return 0;
201 }

 

posted @ 2014-08-08 16:38  Der_Z  阅读(247)  评论(0编辑  收藏  举报