hdu 5521 Meeting

来源:互联网 发布:南昌金域名都地址 编辑:程序博客网 时间:2024/06/16 12:15



题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5521


分析:一个1到n的图,图被分成了几个集合,集合 i 内的点之间到达的时间是 Wi ,找一个点是的从1点的人和从n点的人接头,时间最短,如果多种答案,把点都输出。


解题思路:不可能在点与点之间建图,这样开销太大了,每加一个集合,可以新加一个点,这样最多不会超过2*maxn,所以链式前向星开这么大即可;


代码如下:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<queue>#define LL long long#define INF LONG_LONG_MAXusing namespace std;const int maxn=1e6+10;struct Edge{    int next,w,to;}edge[maxn*2];LL dis[maxn],vis[maxn],dis2[maxn];int head[maxn],n,m,ecnt;void add(int u,int v,int w){    edge[ecnt].next=head[u];    edge[ecnt].to=v;    edge[ecnt].w=w;    head[u]=ecnt++;}struct HeapNode {    LL dis;    int u;    friend bool operator < (HeapNode A, HeapNode B){        return A.dis > B.dis;    }};void Dj(int s,int ed){    priority_queue <HeapNode> q;    for(int i=0;i<=ed;i++)    {        dis[i]=INF;        vis[i]=0;    }    dis[s]=0;    HeapNode hh;    hh.dis=0;   hh.u=s;    q.push(hh);    while(!q.empty())    {        hh=q.top(); q.pop();        vis[hh.u]=1;        for(int i=head[hh.u];i!=-1;i=edge[i].next)        {            if(!vis[edge[i].to] && dis[edge[i].to]>dis[hh.u]+edge[i].w)            {                dis[edge[i].to]=dis[hh.u]+edge[i].w;                HeapNode hp;                hp.dis=dis[edge[i].to]; hp.u=edge[i].to;                q.push(hp);            }        }    }}int main(){    int t;    int cas=0;    int Next;    scanf("%d",&t);    while(t--)    {        ecnt=0;        memset(head,-1,sizeof(head));        scanf("%d%d",&n,&m);        Next=n+1;        for(int i=0;i<m;i++)        {            int u,w,s;            scanf("%d%d",&w,&s);            for(int j=0;j<s;j++)            {                scanf("%d",&u);                add(u,Next,w);                add(Next,u,0);            }            Next++;        }        Dj(1,n+m+1);        for(int i=0;i<=n;i++)            dis2[i]=dis[i];        Dj(n,n+m+1);        LL ans=INF;        for(int i=1;i<=n;i++)            ans=min(ans,max(dis2[i],dis[i]));        printf("Case #%d: ",++cas);        if(ans<INF)        {            printf("%lld\n",ans);            int flag=0;            for(int i=1;i<=n;i++)            {                if(max(dis[i],dis2[i])==ans)                {                    if(flag)                        printf(" ");                    printf("%d",i);                    flag=1;                }            }            printf("\n");        }        else            printf("Evil John\n");    }    return 0;}



原创粉丝点击