hdu 5521(dijkstra+缩点)

来源:互联网 发布:网络银行系统的组成 编辑:程序博客网 时间:2024/06/06 00:24

题意:题目大意:A,B两个人分别在1和n区。求碰面区间使得两人所花时间最短

分析: 因为是以集合给出,所以按集合中的边数两两建边会导致边数过多,所以一个集合添加一个缩点,到缩点的距离为当前集合的值

#include <cstdio>#include <cstring>#include <iostream>#include <queue>#include <algorithm>#include <vector>using namespace std;typedef long long int ll;typedef pair<int,int> P;typedef pair<long long int ,int > PI;#define INF 0x3f3f3f3f#define maxn 200050vector<P>E[maxn];ll dis[maxn];ll disc[maxn];int T;int n , m ;void dijkstra(int s, ll *d){    for(int i = 0 ; i < maxn ; ++i)        d[i] = INF;    d[s] = 0;    priority_queue<PI ,vector<PI> , greater<PI> >Q;    Q.push(PI(0,s));    while(!Q.empty())    {        ll c = Q.top().first;        int u = Q.top().second;        Q.pop();        if( d[u] < c )continue;        for(int i = 0 ; i < E[u].size() ; ++i)        {            int v = E[u][i].first;            ll w = E[u][i].second;            if( d[v] > d[u] + w )            {                d[v] = d[u] + w;                Q.push(PI(d[v],v));            }        }    }}int main(){    cin >> T;    int cas = 0;    while( T-- )    {        for(int i = 0 ; i< maxn ; ++i)E[i].clear();        cin >> n >> m ;        for(int i = 1 ; i <= m ; ++i)        {            int c , k ;            scanf("%d %d",&c,&k);            for(int j = 0 ; j < k ; ++j)            {                int b;                scanf("%d",&b);                E[i + n].push_back(P(b,c));                E[ b ].push_back(P(i+n,0));            }        }        dijkstra(1,dis);        dijkstra(n,disc);        ll ans = INF;        for(int i = 1 ; i <= n ; ++i){            ans = min(ans,max(dis[i],disc[i]));        }        printf("Case #%d: ",++cas);        if( ans == INF )        {            printf("Evil John\n");            continue;        }        else printf("%lld\n",ans);        priority_queue<int,vector<int>,greater<int> >Q;        for(int i = 1 ; i <= n ; ++i){            if(  disc[i] <= ans && dis[i] <= ans ){                Q.push(i);            }        }        while( Q.size() > 1 ){            printf("%d ",Q.top());            Q.pop();        }        printf("%d\n",Q.top());Q.pop();    }}