Meeting HDU - 5521 最短路/虚拟点建图

给许多个组,每个组内点可以花相同时间互相抵达,

可以通过加虚拟点,入边t,出边0来完成建图

其他就是比较恶心的输出以及一个微妙的特判了,具体可以看代码最后的部分,

debug良久猜了一个n=2的hack,加上这个就pe了,难以描述

//#include<bits/stdc++.h>  
//#pragma comment(linker, "/STACK:1024000000,1024000000")   
#include<stdio.h>  
#include<algorithm>  
#include<queue>  
#include<string.h>  
#include<iostream>  
#include<math.h>  
#include<set>  
#include<map>  
#include<vector>  
#include<iomanip>  
using namespace std;  
  
const double pi=acos(-1.0);  
#define ll long long  
#define pb push_back

#define sqr(a) ((a)*(a))
#define dis(a,b) sqrt(sqr(a.x-b.x)+sqr(a.y-b.y))
#define FOR(a) for(int i=1;i<=a;i++)
const double eps=1e-10;
const int maxn=2e5+56;
const int inf=0x3f3f3f3f;

int n,m;   
  
struct EDGE{int v;ll w;};  
vector<EDGE>G[maxn];  
void addedge(int u,int v,int w){  
    G[u].pb((EDGE){v,1ll*w});   
}  
struct NODE{  
    int v;ll d;  
    friend bool operator<(NODE a,NODE b){return a.d>b.d;}  
};  
ll d[maxn][2],vis[maxn];  
void dij(int from,int to,int tic){
  	memset(vis,0,sizeof vis);	
    for(int i=0;i<maxn;i++)d[i][tic]=9e18;  
    d[from][tic]=0;  
    priority_queue<NODE>Q;  
    NODE now=(NODE){from,0};  
    Q.push(now);  
    while(!Q.empty()){  
        NODE now=Q.top();Q.pop();  
        int u=now.v;  
        if(vis[u])continue;  
        vis[u]=1;  
        for(int i=0;i<G[u].size();i++){  
            if(d[G[u][i].v][tic]>d[u][tic]+G[u][i].w){  
                d[G[u][i].v][tic]=d[u][tic]+G[u][i].w;  
                NODE nxt=(NODE){G[u][i].v,d[G[u][i].v][tic]};  
                Q.push(nxt);  
            }  
        }  
    }  
} 

int main(){
	int T;scanf("%d",&T);
	int kase=0;
	while(T--){
		printf("Case #%d: ",++kase);

		scanf("%d%d",&n,&m);

		for(int i=1;i<=n+m;i++)G[i].clear();

		for(int i=1;i<=m;i++){
			int t,cnt;
			scanf("%d%d",&t,&cnt);
			for(int j=1;j<=cnt;j++){
				int x;scanf("%d",&x);
				addedge(x,n+i,t);
				addedge(n+i,x,0);
			}
		}
		dij(1,n,0);
		dij(n,1,1);

		ll ans=9e18;
		for(int i=2;i<n;i++){
			ans=min(ans,max(d[i][0],d[i][1]));
		}
		if(ans==9e18){
			puts("Evil John");continue;
		}else{
			printf("%lld\n",ans);
			int block=0;
			if(ans==d[1][1]){printf("1");block=1;}
			for(int i=2;i<n;i++){
				if(ans==max(d[i][0],d[i][1])){
					if(block)printf(" %d",i);else{
						printf("%d",i);block=1;
					}
				}
			}
			if(ans==d[n][0]){
				if(block)printf(" %d",n);
				else printf("%d",n);
			}
			
			puts("");
		}
	}
}


posted @ 2017-10-10 01:34  Drenight  阅读(197)  评论(0编辑  收藏  举报