显然的最短路问题 如果直接构图 ,集合Ei中的每个点都连一条边到其他点 可能会有 1012 条边 如果对集合Ei , 建一个虚拟节点Vi Vi到没个Ei内的点花费为ti/2 那Ei内任意一个点到其他点就是 ti的花费 跑2遍Dijkstra即可
#include<iostream> #include<cstdlib> #include<cstdio> #include<string> #include<vector> #include<deque> #include<queue> #include<algorithm> #include<set> #include<map> #include<stack> #include<ctime> #include <string.h> #include<math.h> using namespace std; #define ll long long #define pii pair<int,int> const int inf=1e9+7; const int N = 2e5+5; const int M = 1e6+5; char CH; int X; inline int read(){ while(!isdigit(CH=getchar())); X=CH-'0'; while(isdigit(CH=getchar())){ X=X*10+CH-'0'; } return X; } struct Edge{ int to,w,next; }edge[N*2+M*2]; int head[N+M]; inline void addEdge(int k,int u,int v,int w){ edge[k].to=v; edge[k].w=w; edge[k].next=head[u]; head[u]=k; } int dis1[N*2+M*2]; int dis2[N*2+M*2]; bool used[N*2+M*2]; void Dijkstra(int*dis,int st,int n){ fill(dis,dis+n+1,inf); fill(used,used+n+1,false); priority_queue<pii,vector<pii>,greater<pii> >que; que.push(make_pair(0,st)); dis[st]=0; used[st]=true; while(!que.empty()){ pii f=que.top(); que.pop(); int u=f.second; int disNow=f.first; for(int i=head[u];i!=-1;i=edge[i].next){ int to=edge[i].to; int w=edge[i].w; if(used[to]==false&&dis[to]>dis[u]+w){ dis[to]=dis[u]+w; used[to]=true; que.push(make_pair(dis[to],to)); } } } } int main() { //freopen("/home/lu/Documents/r.txt","r",stdin); int T=read(); for(int t=1;t<=T;++t){ int n=read(),m=read(); fill(head,head+n+m+1,-1); int numEdge=0; for(int i=1;i<=m;++i){ int t=read(),s=read(); for(int j=1;j<=s;++j){ int to=read(); addEdge(numEdge++,n+i,to,t); addEdge(numEdge++,to,n+i,t); } } Dijkstra(dis1,1,n+m); Dijkstra(dis2,n,n+m); vector<int>ans; int minAns=inf; for(int i=1;i<=n;++i){ minAns=min(minAns,max(dis1[i],dis2[i])); } if(minAns<inf){ for(int i=1;i<=n;++i){ if(minAns==max(dis1[i],dis2[i])){ ans.push_back(i); } } printf("Case #%d: %d\n",t,minAns/2); for(int i=0;i<ans.size()-1;++i){ printf("%d ",ans[i]); } printf("%d",ans.back()); putchar('\n'); } else{ printf("Case #%d: %s\n",t,"Evil John"); } } return 0; }