Marriage Match IV
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2524 Accepted Submission(s): 755
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?
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
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
题意:给你N个点和M条单向边,再给你起点和终点,问你从起点到终点最多有几条边不重复的最短路径。
思路:先SPFA跑一遍最短路,再重新建图-->把最短路上的边加进图,边权改为1,接下来就是求起点到终点的最大流了。
AC代码:
#include
#include
#include
#include
#include
#include
#define MAXN 1000+10
#define MAXM 200000+10
#define INF 10000000
using namespace std;
struct Edge//求最大流
{
int from, to, cap, flow, next;
}edge[MAXM];
int head[MAXN], edgenum;
int cur[MAXN];
struct Dist//求最短路
{
int from, to, val, next;
}DD[MAXM];
int dead[MAXN], DDnum;
int dist[MAXN];
bool vis[MAXN];
int N, M;
int sx, ex;
void initEdge()
{
edgenum = 0;
memset(head, -1, sizeof(head));
}
void initDist()
{
DDnum = 0;
memset(dead, -1, sizeof(dead));
}
void addEdge(int u, int v, int w)
{
Edge E1 = {u, v, w, 0, head[u]};
edge[edgenum] = E1;
head[u] = edgenum++;
Edge E2 = {v, u, 0, 0, head[v]};
edge[edgenum] = E2;
head[v] = edgenum++;
}
void addDist(int u, int v, int w)
{
Dist E1 = {u, v, w, dead[u]};
DD[DDnum] = E1;
dead[u] = DDnum++;
// Dist E2 = {v, u, w, dead[v]};
// DD[DDnum] = E1;
// dead[v] = DDnum++;
}
void getDist()
{
int a, b, c;
while(M--)
{
scanf("%d%d%d", &a, &b, &c);
addDist(a, b, c);
}
scanf("%d%d", &sx, &ex);
}
void SPFA()//求最短路
{
queue Q;
for(int i = 1; i <= N; i++)
{
dist[i] = i==sx ? 0 : INF;
vis[i] = i==sx ? true : false;
}
Q.push(sx);
while(!Q.empty())
{
int u = Q.front();
Q.pop();
vis[u] = false;
for(int i = dead[u]; i != -1; i = DD[i].next)
{
Dist E = DD[i];
if(dist[E.to] > dist[u] + E.val)
{
dist[E.to] = dist[u] + E.val;
if(!vis[E.to])
{
vis[E.to] = true;
Q.push(E.to);
}
}
}
}
//printf("%d\n", dist[ex]);
}
void getEdge()
{
for(int i = 1; i <= N; i++)
{
for(int j = dead[i]; j != -1; j = DD[j].next)
{
Dist E = DD[j];
if(dist[E.to] == dist[i] + E.val)
//printf("%d->%d ", i, E.to),
addEdge(i, E.to, 1);//加入最短路的边
}
}
}
bool BFS(int start, int end)//寻找增广路
{
queue Q;
memset(dist, -1, sizeof(dist));
memset(vis, false, sizeof(vis));
Q.push(start);
dist[start] = 0, vis[start] = true;
while(!Q.empty())
{
int u = Q.front();
Q.pop();
for(int i = head[u]; i != -1; i = edge[i].next)
{
Edge E = edge[i];
if(!vis[E.to] && E.cap > E.flow)
{
vis[E.to] = true;
dist[E.to] = dist[u] + 1;//建立层次图
if(E.to == end) return true;//找到路径
Q.push(E.to);
}
}
}
return false;
}
int DFS(int x, int a, int end)
{
if(x == end || a == 0) return a;
int flow = 0, f;
for(int &i = cur[x]; i != -1; i = edge[i].next)
{
Edge &E = edge[i];
if(dist[E.to] == dist[x] + 1 && (f = DFS(E.to, min(E.cap - E.flow, a), end)) > 0)
{
E.flow += f;
edge[i^1].flow -= f;
flow += f;
a -= f;
if(a == 0) break;
}
}
return flow;
}
int Maxflow(int start, int end)
{
int flow = 0;
while(BFS(start, end))
{
memcpy(cur, head, sizeof(head));
flow += DFS(start, INF, end);
}
return flow;
}
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
scanf("%d%d", &N, &M);
initDist();
getDist();//建图
SPFA();//求出最短路
initEdge();
getEdge();//建新图
printf("%d\n", Maxflow(sx, ex));
}
return 0;
}