HDU 5521 Meeting 化简边的最短路

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ctrss/article/details/52025027

Meeting

Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 1376    Accepted Submission(s): 441


Problem Description
Bessie and her friend Elsie decide to have a meeting. However, after Farmer John decorated his
fences they were separated into different blocks. John's farm are divided into n blocks labelled from 1 to n.
Bessie lives in the first block while Elsie lives in the n-th one. They have a map of the farm
which shows that it takes they ti minutes to travel from a block in Ei to another block
in Ei where Ei (1im) is a set of blocks. They want to know how soon they can meet each other
and which block should be chosen to have the meeting.
 

Input
The first line contains an integer T (1T6), the number of test cases. Then T test cases
follow.

The first line of input contains n and m2n105. The following m lines describe the sets Ei (1im). Each line will contain two integers ti(1ti109) and Si (Si>0) firstly. Then Si integer follows which are the labels of blocks in Ei. It is guaranteed that mi=1Si106.
 

Output
For each test case, if they cannot have the meeting, then output "Evil John" (without quotes) in one line.

Otherwise, output two lines. The first line contains an integer, the time it takes for they to meet.
The second line contains the numbers of blocks where they meet. If there are multiple
optional blocks, output all of them in ascending order.
 

Sample Input
2 5 4 1 3 1 2 3 2 2 3 4 10 2 1 5 3 3 3 4 5 3 1 1 2 1 2
 

Sample Output
Case #1: 3 3 4 Case #2: Evil John
Hint
In the first case, it will take Bessie 1 minute travelling to the 3rd block, and it will take Elsie 3 minutes travelling to the 3rd block. It will take Bessie 3 minutes travelling to the 4th block, and it will take Elsie 3 minutes travelling to the 4th block. In the second case, it is impossible for them to meet.
 

Source
 



题意:一张图有n个点,现在有m个集合,图以集合的形式给出,每个集合中所有点的距离相等,一个人从1出发,一个人从n出发,现要求求出一点,使得两人到这点的最大距离最小,如果有多个点则全部输出

思路:如果边很少的话,就是裸的最短路,从1出发做一次,从n出发做一次,枚举每个点求出最小的最大距离即可。但是现在集合中最多有1e6个点,有c(1e6,2)条边,如果不加修改直接套进最短路肯定会超时的。这道题有个特点,就是一个集合里点的距离是相等的,那么可以把一个距离为d的集合只看成两个点in与out,将这两个点的距离赋为d,集合中所有点连向in,out再连向所有的集合中的点,这样边数就不超过1e6了。



#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<queue>
#include<string.h>
#include<vector>
#define N 1000006
long long INF=100000000000000000;
using namespace std;
int n,m;
struct node
{
	long long d;
	int to;
};
vector<node>a[N];
long long dis1[N];
int vis[N];
long long disn[N];
int ans[N];
void spfa(int x,long long d[])
{
	queue<int> q;
	for(int i=1;i<=n+2*m;i++)d[i]=INF;
	memset(vis,0,sizeof(vis));
	q.push(x);
	vis[x]=1;
	d[x]=0;
	while(!q.empty())
	{
		int u=q.front(),v;
		q.pop();
		vis[u]=0;
		int ll=a[u].size();
		for(int j=0;j<ll;j++)
		{
			v=a[u][j].to;
			if(d[u]+a[u][j].d<d[v])
			{
				d[v]=d[u]+a[u][j].d;
				if(vis[v]==0)
				{
					vis[v]=1;
					q.push(v);
				}
			}
		}
	}
}

int main()
{
	int T,t;
	scanf("%d",&T);
	for(int t=1;t<=T;t++)
	 {  memset(ans,0,sizeof(ans));
	 	scanf("%d%d",&n,&m);
	 	memset(vis,0,sizeof(vis));
	 	for(int i=1;i<=2*m+n;i++)a[i].clear();
	 	for(int i=1;i<=m;i++)
	 	{   int nn;
	 	    long long di;
	 		scanf("%I64d%d",&di,&nn);
	 		int in=i+n;
	 		int out=i+n+m;
	 		node temp;
	 		temp.d=di;
	 		temp.to=out;
	 		a[in].push_back(temp);
	 		for(int j=1;j<=nn;j++)
	 		{
	 		 int x;
	 		 scanf("%d",&x);
	 		 node temp;
	 		 temp.d=0;
	 		 temp.to=x;
			 a[out].push_back(temp);
			 temp.to=in;
			 a[x].push_back(temp); 	
			 }
		 }
		 spfa(1,dis1);
		 spfa(n,disn);
		 int flag=0;
		 long long mind=INF;
		 for(int i=1;i<=n;i++)
		 {
		 	if(max(dis1[i],disn[i])<mind)
		 	{mind=max(dis1[i],disn[i]);
		    flag=1;
			}
		 }
		 printf("Case #%d: ",t);
		 if(flag==0)printf("Evil John\n");
		 else
		 {
		 printf("%lld\n",mind);
		 int cnt=0;
		 for(int i=1;i<=n;i++)
		 if(max(dis1[i],disn[i])==mind)ans[++cnt]=i;
		 for(int i=1;i<cnt;i++)printf("%d ",ans[i]);
		 printf("%d\n",ans[cnt]);
		 }
	 }
	 return 0;
}

在网上找图论题的题解都十分痛苦,别人的存图方式总是看不懂,只能自己硬写了,没想到竟然很神的1A了……暑假集训到现在,感觉别的都没什么长进,就是抄题解越来越快了,感觉要跪啊……
展开阅读全文

没有更多推荐了,返回首页