Marriage Match IV
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2544 Accepted Submission(s): 766
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
题目大意:给你一个图,问你起点到终点有多少条最短路径。选了其中一条路径这条路径的所有走过的边都不能再走。
思路:先一遍dij求出起点到所有点的最短路,然后把所有在最短路里面的边都保存下来,构造一个新图,建一个源点在起点汇点在终点的图,求出这个图的最小割,就是最后的答案了。
#include <cstdio>
#include <cstring>
#include <queue>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <cstdlib>
#define lson l,mid,o<<1
#define rson mid + 1,r ,o<<1|1
using namespace std;
const int maxn = 20005;
int ma = 2011111111;
struct Edge
{
int v,next,w;
}e[maxn * 20];
int a[maxn],head[maxn],cnt,n,m,edge[maxn * 20][3],ed;
void add(int a,int b,int c)
{
e[cnt].v = b;
e[cnt].w = c;
e[cnt].next = head[a];
head[a] = cnt++;
}
void init()
{
memset(head,-1,sizeof(head));
cnt = 0;
}
int d[maxn],vis[maxn];
struct node
{
int vis,val;
node(){};
node(int a,int b)
{
vis = a;val = b;
}
friend bool operator <(node a,node b)
{
return a.val > b.val;
}
};
void dij(int st)
{
int i;
for(i = 1; i <= n; i++)
{
d[i] = ma;
}
d[st] = 0;
memset(vis,0,sizeof(vis));
priority_queue<node> q;
q.push(node(st,0));
while(!q.empty())
{
node w = q.top();
q.pop();
int begin = w.vis;
if(vis[begin] == 1)
continue;
vis[begin] = 1;
for(i = head[begin]; i != -1; i = e[i].next)
{
int end = e[i].v;
if(d[end] > d[begin] + e[i].w)
{
d[end] = d[begin] + e[i].w;
q.push(node(end,d[end]));
}
}
}
}
int used[2050];
int INF = 2100000000;
int level[2050];
void bfs(int u,int vv)
{
memset(level,0,sizeof(level));
int pre[10005];
int begin = 0,end = 1;
pre[0] = u;
level[u] = 0;
while(begin < end)
{
int i;
if(level[vv] != 0)
return;
int st = pre[begin];
for(i = head[st]; i != -1;i = e[i].next)
{
int v = e[i].v;
if(e[i].w == 0)
continue;
if(level[v] == 0)
{
level[v] = level[st] + 1;
pre[end++] = v;
if(v == vv)
return;
}
}
begin++;
}
}
int dfs(int u,int t,int c)
{
if(c == 0||u == t)
{
return c;
}
used[u] = 1;
int i;
int flow = 0;
for(i = head[u]; i != -1; i = e[i].next)
{
int end = e[i].v;
if(used[end])
continue;
if(level[end] > level[t])
continue;
int f = dfs(end,t,min(e[i].w,c));
if(f > 0)
{
flow += f;
e[i].w -= f;
e[i ^ 1].w += f;
c -= f;
if(c == 0)
break;
}
}
return flow;
}
int f(int u,int v)//u是源点,v是汇点
{
int flow = 0;
for(;;)
{
memset(used,0,sizeof(used));
bfs(u,v);
if(level[v] == 0)
return flow;
int f = dfs(u,v,INF);
flow += f;
}
return flow;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
init();
scanf("%d %d",&n,&m);
int st;
int i,j;
for(i = 0; i < m; i++)
{
int q,w,e1;
scanf("%d %d %d",&q,&w,&e1);
edge[i][0] = q;
edge[i][1] = w;
edge[i][2] = e1;
if(q == w)
continue;
add(q,w,e1);
}
scanf("%d %d",&st,&ed);
dij(st);
if(d[ed] == ma)
{
printf("0\n");
continue;
}
init();
for(i = 0; i < m; i++)
{
if(edge[i][0] == edge[i][1])
continue;
if(d[edge[i][0]] + edge[i][2] == d[edge[i][1]])
{
add(edge[i][0],edge[i][1],1);
add(edge[i][1],edge[i][0],0);
}
}
printf("%d\n",f(st,ed));
}
return 0;
}