HDU 5521 Meeting 化简边的最短路

8 篇文章 0 订阅
3 篇文章 0 订阅

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  m 2n105 . 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了……暑假集训到现在,感觉别的都没什么长进,就是抄题解越来越快了,感觉要跪啊……
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值