Marriage Match IV
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 6414 Accepted Submission(s): 1851
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<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
题意:一个人去见他女票(FFF)然后这个人在A城市 女票在B城市,现在给出n个城市和m条路 问这个人能走多少种路到女票的城市,走过的路不能再走,走过的点可以
思路:我一开始是这样判断的,题目中说两个城市不止一条路,所以我筛选出最小的一条,如果又相同的就++,之后最短路出最短的长度最大流出一条路再判断是不是最短的路径。。。。就这样,我wa了
之后去看了一下大佬的代码,大佬是这样做的:先最短路出起点到终点的距离,然后dis x +Map x y ==dis y成立的话(不知道为什么这里用[]会显示不了),说明这条路是最短路。然后我们记录。
然后跑一下最大流就可以得出答案
AC代码:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
const int maxn=10000+10;
const int maxm=200000+20;
const int INF=0x7f7f7f7f;
struct Node
{
int end,value,next;
}map[maxm<<2];
struct node
{
int next,value,end;
}Map[maxm<<2];
int head[maxm],n,m,sum;
int Head[maxm],Sum;
int pre[maxn],dis[maxn];
bool vis[maxn];
int a[maxm],b[maxm],c[maxm];
void Init()
{
sum=0;Sum=0;
memset(Head,-1,sizeof(Head));
memset(map,0,sizeof(map));
memset(head,-1,sizeof(head));
memset(Map,0,sizeof(Map));
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
return ;
}
void addedge(int start,int end,int value)
{
map[sum].end=end;
map[sum].value=value;
map[sum].next=head[start];
head[start]=sum++;
return ;
}
void addMap(int start,int end,int value)
{
Map[Sum].end=end;
Map[Sum].value=value;
Map[Sum].next=Head[start];
Head[start]=Sum++;
return ;
}
void spfa(int start,int end) //找出最短路
{
queue<int> q;
memset(dis,INF,sizeof(dis));
memset(vis,false,sizeof(vis));
dis[start]=0;vis[start]=true;
q.push(start);
while (!q.empty())
{
int now=q.front();
q.pop();
vis[now]=false;
// cout<<now<<endl;
for (int i=head[now];i!=-1;i=map[i].next)
if (dis[map[i].end]>dis[now]+map[i].value)
{
// cout<<now<<endl;
dis[map[i].end]=dis[now]+map[i].value;
if (vis[map[i].end]==false)
{
q.push(map[i].end);
vis[map[i].end]=true;
}
}
}
}
bool bfs(int start,int end) //找出符合的路线
{
queue<int> q;
memset(pre,-1,sizeof(pre));
pre[start]=0;
q.push(start);
while (!q.empty())
{
int now=q.front();
q.pop();
for (int i=Head[now];i!=-1;i=Map[i].next)
if (pre[Map[i].end]==-1&&Map[i].value>0)
{
pre[Map[i].end]=pre[now]+1;
q.push(Map[i].end);
}
}
return pre[end]>=0;
}
int dfs(int now,int flow,int end)
{
if (now==end)
return flow;
int temp=0,deta=0;
for (int i=Head[now];i!=-1;i=Map[i].next)
if (pre[Map[i].end]==pre[now]+1&&Map[i].value>0)
{
temp=dfs(Map[i].end,min(flow-deta,Map[i].value),end);
if (temp>0)
{
Map[i].value-=temp;
Map[i^1].value+=temp;
deta=deta+temp;
if (deta==flow) break;
}
else pre[Map[i].end]=-1;
}
// cout<<now<<" "<<end<<endl;
return deta;
}
int dinic(int x,int start,int end)
{
int ans=0;
while (bfs(start,end)==true)
ans=ans+dfs(start,INF,end);
return ans;
}
int main()
{
int t,low,ans;
int start,end,value;
cin>>t;
while (t--)
{
scanf("%d%d",&n,&m);
Init();
for (int i=1;i<=m;i++) //map
{
scanf("%d%d%d",&a[i],&b[i],&c[i]);
if (a[i]==b[i]) continue;
addedge(a[i],b[i],c[i]);
}
scanf("%d%d",&start,&end);
spfa(start,end);
// cout<<diss[end]<<endl;
// cout<<dise[start]<<endl;
for (int i=1;i<=m;i++)
if (dis[a[i]]+c[i]==dis[b[i]]) //当符合条件的时候记录
{
addMap(a[i],b[i],1);
addMap(b[i],a[i],0); //反向记录的时候权值为0
}
/* for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
if (j==n) cout<<Map[i][j]<<endl;
else cout<<Map[i][j]<<" ";*/
ans=dinic(low,start,end);
cout<<ans<<endl;
}
return 0;
}
记得要用C++交,好像G++交会超时。。。