首页 > 代码库 > 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 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。