Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 6167 Accepted Submission(s): 1925 Problem Description Bessie and her friend Elsie decide to have a meeting. However, after Farmer John decorated his
Input The first line contains an integer T (1≤T≤6) , the number of test cases. Then T test cases
Output For each test case, if they cannot have the meeting, then output "Evil John" (without quotes) in one line.
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 2015ACM/ICPC亚洲区沈阳站-重现赛(感谢东北大学)
Recommend wange2014
|
题意:给n个点,m个集合,每个集合里有si 个点,相同集合内部点的距离为fi,A在1号点,B在n号点,A B要见面,他们只能在节点见面不可以在路上见面,AB走单位距离话费1分钟,问最少话费几分钟可以见面,在最小话费的前提下有几个节点可以作为见面的点,按照字典序输出可以见面的地点,如果没有输出Evil John 。
思路:集合缩点,添加一个M个源点,源点→点 权为w,点→源点 权为0集合缩点,添加一个M个源点,源点→点 权为w,点→源点 权为0
1开始跑一遍最短路,n开始跑一遍最短路,枚举相遇的点就可以了
代码:
#include <iostream>
#include <queue>
#include <algorithm>
#include <string.h>
#include <stdio.h>
#include <math.h>
using namespace std;
const long long INF=pow(10,18);
const int maxm=2111110;
const int maxn=1111110;
struct sa
{
int num;
long long ww;
}ans[maxn];
struct EdgeNode
{
int to;
int w;
int next;
};
EdgeNode edges[maxm];
int head[maxn],edge;
bool vis[maxn];
int a[maxn];
int outque[maxn];
queue<int>que;
long long dis[maxn];
long long disx[maxn],disy[maxn];
int T,n,m,t,s;
long long cmp(const sa x,const sa y)
{
return x.ww<y.ww;
}
void addedge(int u,int v,int c)
{
edges[edge].w=c;
edges[edge].to=v;
edges[edge].next=head[u];
head[u]=edge++;
}
void init()
{
memset(head,-1,sizeof(head));
edge=0;
}
void spfa(int s,int n)
{
int u;
for(int i=0; i<=m+n+5; i++)
dis[i]=INF;
memset(vis,0,sizeof(vis));
while(!que.empty())
que.pop();
que.push(s);
vis[s]=true;
dis[s]=0;
while(!que.empty())
{
u=que.front();
que.pop();
vis[u]=false;
for(int i=head[u]; i!=-1; i=edges[i].next)
{
int v=edges[i].to;
int w=edges[i].w;
if(dis[v]>dis[u]+w)
{
dis[v]=dis[u]+w;
if(!vis[v])
{
vis[v]=true;
que.push(v);
}
}
}
}
}
int top;
int main()
{
int cases=1;
scanf("%d",&T);
while(T--)
{
init();
scanf("%d%d",&n,&m);
int start=n+1;
for(int i=1; i<=m; i++)
{
scanf("%d%d",&t,&s);
for(int j=1; j<=s; j++)
{
scanf("%d",&a[j]);
addedge(a[j],start,t);
addedge(start,a[j],0);
}
start++;
}
spfa(1,n+m+1);
for(int i=1; i<=n; i++)
{
disx[i]=dis[i];
}
spfa(n,n+m+1);
for(int i=1; i<=n; i++)
{
disy[i]=dis[i];
}
printf("Case #%d: ",cases++);
if(disx[n]==INF)
{
printf("Evil John\n");
continue;
}
long long sum=INF;
int flag=0;
for(int i=1; i<=n; i++)
{
ans[i].ww=max(disx[i],disy[i]);
if(sum>ans[i].ww)
{
sum=ans[i].ww;
flag=i;
}
ans[i].num=i;
}
printf("%I64d\n",sum);
printf("%d",flag);
for(int i=1;i<=n;i++)
{
if(ans[i].ww==sum&&i!=flag)
printf(" %d",i);
}
printf("\n");
}
return 0;
}