首页 > 代码库 > HDU 3416 Marriage Match IV

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 }