MeetingTime Limit: 12000/6000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 5041 Accepted Submission(s): 1581 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. |
題意:
給你n個城市,m個路徑集合,要你從城市1走到城市n。每個路徑集合包括一個T和S,接下來有S個城市。表示這S個城市之間的任意兩個城市要行走要花費的時間是T,兩個城市可能會出現在多個路徑集合中。
做法:
一道看似簡單的最短路,但是有一個問題就是邊集會因爲兩兩要建立邊的關係而數量龐大,這個時候就要做一個簡單的處理,將一個路徑集合中的點連接到第S+1個店上,時間變爲原來的一半,如城市1,2,3之間要花費4小時,這個時候建立一個額外的店1',讓這三個城市到達1'的時間變爲2,這樣的話1想到2就要經過1',讓時間還是原來的4,這樣的處理可以大大減少需要的邊。然後只要把點1和點n丟進dijkstra跑一下就好了。
需要的點最多有 n+最大路徑集合數S=1e6+1e5.每個集合需要多加一個邊
需要的邊最多有 S*2,建立雙向邊
代碼如下:
#include<queue>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
const int maxn=1200005;
const int inf=0x3f3f3f3f;
ll dist1[maxn],t,distn[maxn];
int cnt,head[maxn],n,m,now,vis[maxn];
vector<int> ans;
struct node{
int to,next,w;
}e[maxn*2];
struct Node{
int dis,id;
Node(int dis,int id):dis(dis),id(id){}
bool operator < (const Node &a)const{
return dis>a.dis;
}
};
void add(int u,int v,int w){
e[cnt].to=v,e[cnt].w=w;
e[cnt].next=head[u],head[u]=cnt++;
}
void init(){
memset(head,-1,sizeof(head));
cnt=0;
}
void dij(int st,ll dis[]){
for(int i=1;i<=now;i++){
dis[i]=1e18;
}
memset(vis,0,sizeof(vis));
dis[st]=0;
priority_queue<Node> q;
q.push(Node(0,st));
vis[st]=1;
while(!q.empty()){
int u=q.top().id; q.pop();
vis[u]=1;
for(int i=head[u];~i;i=e[i].next){
int v=e[i].to;
if(vis[v]) continue;
if(dis[v]-(ll)e[i].w>dis[u]){
dis[v]=dis[u]+(ll)e[i].w;
q.push(Node(dis[v],v));
}
}
}
}
int main(){
int t,n,m,ti,s,x,cas=0;
cin>>t;
while(t--){
init();
scanf("%d%d",&n,&m);
now=n;
for(int i=1;i<=m;i++){
scanf("%d%d",&ti,&s);
now++;
for(int j=0;j<s;j++){
scanf("%d",&x);
add(x,now,ti);
add(now,x,ti);
}
}
dij(1,dist1);
dij(n,distn);
printf("Case #%d: ",++cas);
if(dist1[n]>=1e18){
printf("Evil John\n");
}
else {
ans.clear();
ll now=1e18;
for(int i=1;i<=n;i++){
ll nowmin=max(dist1[i],distn[i]);
if(now>nowmin/2){
ans.clear();
ans.push_back(i);
now=nowmin/2;
}
else if(now==nowmin/2){
ans.push_back(i);
}
}
printf("%lld\n",now);
for(int i=0;i<ans.size();i++){
printf("%d%c",ans[i],i==ans.size()-1?'\n':' ');
}
}
}
return 0;
}