HDU3416-最短路加网络流

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++交会超时。。。

发布了46 篇原创文章 · 获赞 2 · 访问量 3210

猜你喜欢

转载自blog.csdn.net/z1164754004z/article/details/88358674
今日推荐