题目链接:https://vjudge.net/problem/HDU-3416
Marriage Match IV
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4710 Accepted Submission(s): 1412
Problem Description
Do not sincere non-interference。
Like that show, now starvae also take part in a show, but it take place between city A and B. Starvae is in city A and girls are in city B. Every time starvae can get to city B and make a data with a girl he likes. But there are two problems with it, one is starvae must get to B within least time, it's said that he must take a shortest path. Other is no road can be taken more than once. While the city starvae passed away can been taken more than once.
So, under a good RP, starvae may have many chances to get to city B. But he don't know how many chances at most he can make a data with the girl he likes . Could you help starvae?
Like that show, now starvae also take part in a show, but it take place between city A and B. Starvae is in city A and girls are in city B. Every time starvae can get to city B and make a data with a girl he likes. But there are two problems with it, one is starvae must get to B within least time, it's said that he must take a shortest path. Other is no road can be taken more than once. While the city starvae passed away can been taken more than once.
So, under a good RP, starvae may have many chances to get to city B. But he don't know how many chances at most he can make a data with the girl he likes . Could you help starvae?
Input
The first line is an integer T indicating the case number.(1<=T<=65)
For each case,there are two integer n and m in the first line ( 2<=n<=1000, 0<=m<=100000 ) ,n is the number of the city and m is the number of the roads.
Then follows m line ,each line have three integers a,b,c,(1<=a,b<=n,0<c<=1000)it means there is a road from a to b and it's distance is c, while there may have no road from b to a. There may have a road from a to a,but you can ignore it. If there are two roads from a to b, they are different.
At last is a line with two integer A and B(1<=A,B<=N,A!=B), means the number of city A and city B.
There may be some blank line between each case.
For each case,there are two integer n and m in the first line ( 2<=n<=1000, 0<=m<=100000 ) ,n is the number of the city and m is the number of the roads.
Then follows m line ,each line have three integers a,b,c,(1<=a,b<=n,0<c<=1000)it means there is a road from a to b and it's distance is c, while there may have no road from b to a. There may have a road from a to a,but you can ignore it. If there are two roads from a to b, they are different.
At last is a line with two integer A and B(1<=A,B<=N,A!=B), means the number of city A and city B.
There may be some blank line between each case.
Output
Output a line with a integer, means the chances starvae can get at most.
Sample Input
3
7 8
1 2 1
1 3 1
2 4 1
3 4 1
4 5 1
4 6 1
5 7 1
6 7 1
1 7
6 7
1 2 1
2 3 1
1 3 3
3 4 1
3 5 1
4 6 1
5 6 1
1 6
2 2
1 2 1
1 2 2
1 2
Sample Output
2
1
1
Author
starvae@HDU
Source
题意:
求有多少条最短路径,要求边不能够重叠(但题目可以有重边,即两个点之间可以有几条边)。
题解:
1.先用spfa算法求出最短路径,并且筛掉那些不在最短路径上的边。
2.构建网络流图:对于在最短路径上的边u-->v,在网络流图中构建一条边 u-->v,且边权为1,表明这条边只能被走一次。
3.以起点为源点,以终点为汇点,求出最大流,即为答案。
代码如下:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <vector> 6 #include <cmath> 7 #include <queue> 8 #include <stack> 9 #include <map> 10 #include <string> 11 #include <set> 12 using namespace std; 13 typedef long long LL; 14 const int INF = 2e9; 15 const LL LNF = 9e18; 16 const int mod = 1e9+7; 17 const int MAXM = 1e5+10; 18 const int MAXN = 1e3+10; 19 20 vector<pair<int,int> >son[MAXN]; 21 int dis1[MAXN], dis2[MAXN], dis[MAXN], inq[MAXN]; 22 void spfa(int start, int N) 23 { 24 memset(inq, 0, sizeof(inq)); 25 for(int i = 1; i<=N; i++) 26 dis[i] = INF; 27 28 queue<int>Q; 29 Q.push(start); 30 inq[start] = 1; 31 dis[start] = 0; 32 while(!Q.empty()) 33 { 34 int u = Q.front(); 35 Q.pop(); inq[u] = 0; 36 for(int i = 0; i<son[u].size(); i++) 37 { 38 int v = son[u][i].first; 39 int w = son[u][i].second; 40 if(dis[v]>dis[u]+w) 41 { 42 dis[v] = dis[u]+w; 43 if(!inq[v]) 44 { 45 Q.push(v); 46 inq[v] = 1; 47 } 48 } 49 } 50 } 51 } 52 53 struct Edge 54 { 55 int to, next, cap, flow; 56 }edge[MAXM<<2]; 57 int tot, head[MAXN]; 58 int gap[MAXN], dep[MAXN], pre[MAXN], cur[MAXN]; 59 60 void init() 61 { 62 tot = 0; 63 memset(head, -1, sizeof(head)); 64 } 65 66 void add(int u, int v, int w) 67 { 68 edge[tot].to = v; edge[tot].cap = w; edge[tot].flow = 0; 69 edge[tot].next = head[u]; head[u] = tot++; 70 edge[tot].to = u; edge[tot].cap = 0; edge[tot].flow = 0; 71 edge[tot].next = head[v]; head[v] = tot++; 72 } 73 74 int sap(int start, int end, int nodenum) 75 { 76 memset(dep, 0, sizeof(dep)); 77 memset(gap, 0, sizeof(gap)); 78 memcpy(cur, head, sizeof(head)); 79 int u = pre[start] = start, maxflow = 0,aug = INF; 80 gap[0] = nodenum; 81 while(dep[start]<nodenum) 82 { 83 loop: 84 for(int i = cur[u]; i!=-1; i = edge[i].next) 85 { 86 int v = edge[i].to; 87 if(edge[i].cap-edge[i].flow && dep[u]==dep[v]+1) 88 { 89 aug = min(aug, edge[i].cap-edge[i].flow); 90 pre[v] = u; 91 cur[u] = i; 92 u = v; 93 if(v==end) 94 { 95 maxflow += aug; 96 for(u = pre[u]; v!=start; v = u,u = pre[u]) 97 { 98 edge[cur[u]].flow += aug; 99 edge[cur[u]^1].flow -= aug; 100 } 101 aug = INF; 102 } 103 goto loop; 104 } 105 } 106 int mindis = nodenum; 107 for(int i = head[u]; i!=-1; i = edge[i].next) 108 { 109 int v=edge[i].to; 110 if(edge[i].cap-edge[i].flow && mindis>dep[v]) 111 { 112 cur[u] = i; 113 mindis = dep[v]; 114 } 115 } 116 if((--gap[dep[u]])==0)break; 117 gap[dep[u]=mindis+1]++; 118 u = pre[u]; 119 } 120 return maxflow; 121 } 122 123 int u[MAXM], v[MAXM], w[MAXM]; 124 int main() 125 { 126 int T, n, m; 127 scanf("%d", &T); 128 while(T--) 129 { 130 int start, end; 131 scanf("%d%d", &n,&m); 132 for(int i = 1; i<=m; i++) 133 scanf("%d%d%d", &u[i], &v[i], &w[i]); 134 scanf("%d%d", &start, &end); 135 136 for(int i = 1; i<=n; i++) son[i].clear(); 137 for(int i = 1; i<=m; i++) son[u[i]].push_back(make_pair(v[i], w[i])); 138 spfa(start, n); 139 memcpy(dis1, dis, sizeof(dis1)); 140 int distance = dis1[end]; 141 142 for(int i = 1; i<=n; i++) son[i].clear(); 143 for(int i = 1; i<=m; i++) son[v[i]].push_back(make_pair(u[i], w[i])); 144 spfa(end, n); 145 memcpy(dis2, dis, sizeof(dis2)); 146 147 init(); 148 for(int i = 1; i<=m; i++) 149 if(dis1[u[i]]+w[i]+dis2[v[i]]==distance) 150 add(u[i], v[i], 1); 151 152 int ans = sap(start, end, n); 153 printf("%d ", ans); 154 } 155 }