zoukankan      html  css  js  c++  java
  • hdu-6166(最短路+二进制分组)

    题意:给你n个点m条边的有向图,然后再给你k个不同的点,问你这k个点的最小距离;

    解题思路:这道题最需要注意的就是k个点一定是不同的,那么有一个结论就是任意两个不同的数字中,在他们的二进制地表示中,一定有一位是不同的,这样,我们就可以按照这个规律,把这些数字分成两组,按他们的二进制在某一位是0或者1分组,然后对每一位都跑一次最短路,这里的数据的二进制不超过20位

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #define maxn 100500
    #define inf 0x3f3f3f3f
    using namespace std;
    struct node
    {
        int num;
        int dist;
        node(int _num=0,int _dist=0):num(_num),dist(_dist){}
        friend bool operator<(node a,node b)
        {
            return a.dist>b.dist;
        }
    };
    struct Edge
    {
        int next;
        int to;
        int fa;
        int w;
    }edge[maxn];
    int head[maxn];
    int dist[maxn];
    int cnt;
    int visit[maxn];
    int flag[maxn];
    int n,m;
    int k,x,y,w,t;
    int pow(int u)
    {
        int x=1;
        for(int i=1;i<=u;i++)
            x=x*2;
        return x;
    }
    void add(int u,int v,int w)
    {
        edge[cnt].next=head[u];edge[cnt].w=w;
        edge[cnt].to=v;edge[cnt].fa=u;head[u]=cnt++;
    }
    void dij()
    {
        memset(dist,inf,sizeof(dist));
        priority_queue<node>q;
        for(int i=1;i<=n;i++)
        {
            if(flag[i]==1)
            {
                q.push(node(i,0));dist[i]=0;
            }
        }
        while(!q.empty())
        {
            node now=q.top();q.pop();
            x=now.num;
            for(int i=head[x];i!=-1;i=edge[i].next)
            {
                int v=edge[i].to;
                if(dist[v]>dist[x]+edge[i].w)
                {
                    dist[v]=edge[i].w+dist[x];
                    q.push(node(v,dist[v]));
                }
            }
        }
    }
    int main()
    {
        int tt;
        int temp;
        int cot=0;
        scanf("%d",&tt);
        while(tt--)
        {
            cot++;
            //memset(flag,0,sizeof(flag));
            memset(visit,0,sizeof(visit));
            memset(head,-1,sizeof(head));
            cnt=0;
            scanf("%d%d",&n,&m);
            for(int i=1;i<=m;i++)
            {
                scanf("%d%d%d",&x,&y,&w);
                add(x,y,w);
            }
            scanf("%d",&k);
            for(int i=1;i<=k;i++)
            {
                scanf("%d",&t);
                visit[t]=1;
            }
            int ans=inf;
            for(int i=0;i<20;i++)
            {
                for(int j=1;j<=n;j++)
                {
                    if(!visit[j])
                        continue;
                    temp=pow(i);flag[j]=0;
                    if((j&temp)==0)
                    {
                        flag[j]=1;
                    }
                    else
                        flag[j]=-1;
                }
                dij();
                for(int j=1;j<=n;j++)
                {
                    if(!visit[j])
                        continue;
                    if(flag[j]==-1)
                        ans=min(ans,dist[j]);
                }
                for(int j=1;j<=n;j++)
                {
                    if(!visit[j])
                        continue;
                    temp=pow(i);flag[j]=0;
                    if((j&temp)==0)
                    {
                        flag[j]=-1;
                    }
                    else
                        flag[j]=1;
                }
                dij();
                for(int j=1;j<=n;j++)
                {
                    if(!visit[j])
                        continue;
                    if(flag[j]==-1)
                        ans=min(ans,dist[j]);
                }
            }
            printf("Case #%d: %d
    ",cot,ans);
        }
    }
    

      

    ,每一位分别跑两次最短路,一次是所有的0到所有的1,另一次是所有的1到所有的0,一共是四十次不到,如果根据每次给的n来跑,会更小。

    ps:这里的最短路是多源多汇的;

    代码:

  • 相关阅读:
    [译]GLUT教程
    [译]GLUT教程
    [译]GLUT教程
    strlen,_conntof,sizeof
    《const限定符的使用》
    设备资源管理系统-JFreeChart
    设备资源管理系统-jxl报表
    设备资源管理系统-poi报表
    设备资源管理系统-分页
    设备资源管理系统-日志管理
  • 原文地址:https://www.cnblogs.com/huangdao/p/9484743.html
Copyright © 2011-2022 走看看