HDU 5521 Meeting(建图思维)

题目链接

题解思路:对于完全图而言,图中每一个点都可以直接到达其他点,题目中又已说明每个完全图中边的权值一样,因此我们可以对每个完全图加一个“超级原点”,最后跑两遍 dijkstra 即可。

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<ll,int> PII;
const int MAXN = 2e5+10;
const double EPS = 1e-12;

int T,n,m,cnt,cas;
ll dis1[MAXN],dis2[MAXN];
int path[MAXN];
struct node{
    int to;
    ll cost;
};
vector<node>G[MAXN];

void Dij(int s,ll d[]){
    for(int i=1;i<=n+m;i++)d[i]=1e18;
    d[s]=0;
    priority_queue<PII,vector<PII>,greater<PII> >q;
    q.push(PII(0,s));
    while(!q.empty()){
        PII p=q.top();q.pop();
        int u=p.second;
        if(p.first>d[u])continue;
        for(int i=0;i<G[u].size();i++){
            node v=G[u][i];
            if(d[v.to]>d[u]+v.cost){
                d[v.to]=d[u]+v.cost;
                q.push(PII(d[v.to],v.to));
            }
        }
    }
}

int main()
{
    scanf("%d",&T);
    while(T--){
        scanf("%d %d",&n,&m);
        for(int i=1;i<=n+m;i++)G[i].clear();
        int si;ll ti;
        for(int i=1;i<=m;i++){
            scanf("%lld %d",&ti,&si);
            for(int j=1;j<=si;j++){
                int x;scanf("%d",&x);
                G[n+i].push_back(node{x,ti});
                G[x].push_back(node{n+i,ti});
            }
        }
        Dij(1,dis1);
        Dij(n,dis2);
        ll minn=1e18;
        for(int i=1;i<=n;i++)
            minn=min(minn,max(dis1[i],dis2[i]));
        printf("Case #%d: ",++cas);
        if(minn==1e18)printf("Evil John
");
        else{
            cnt=0;
            printf("%lld
",minn/2);
            for(int i=1;i<=n;i++)
                if(minn==max(dis1[i],dis2[i]))
                    path[++cnt]=i;
            for(int i=1;i<=cnt;i++){
                printf("%d",path[i]);
                if(i!=cnt)printf(" ");
            }
            printf("
");
        }
    }
}

原文地址:https://www.cnblogs.com/Mmasker/p/11917455.html