zoukankan      html  css  js  c++  java
  • 地图游戏

    题目描述

    从前有一个基于一张无向图的游戏,我个人认为是比较无聊,但是出题需要,还是给你们讲讲怎么玩吧。= = 给一张地图,地图上有一些城市,城市之间可能有线路连通,我们用一个无向图来表示以简化概念,每条边有个权值,表示选择这条边需要花费的费用。给定4对顶点(可能重复),求一个权值最小的边集,使得任意一对顶点可以由选出的边集中的边相连。 按照惯例,下面给出一个例子:

    输入格式

    12个整数,nm,分别表示城市的个数和边的个数。

    接下来n行,每行一个字符串,表示每个城市的名字。城市的名字为一个不超过20个字

    符,由小写字母构成的字符串。

    再接下来m行,每行给出s1,s2w,其中s1,s2为城市的名字,w为他们之间边的权值。

    最后,给出4行,每行给出两个字符串,分别为要求的一对城市的名字。

    输出格式

    一行,输出最小的花费。

    样例

    样例输入:

    2 1

    first

    second

    first second 10

    first first

    first first

    second first

    first first

    样例输出:

    10

    Sol

    斯坦纳树模板题,合并一下联通关系就好啦!

    Code

    1. #include <bits/stdc++.h>  
    2. using namespace std;  
    3. int las[10005],nex[10005],Arrive[10005],qz[10005],cnt,K;  
    4. int Bit[100005];  
    5. bool pd[100005];  
    6. int bel[100005],Size[100005],Temp;  
    7. int Lt[505][505];  
    8. int dis[100005][205];  
    9. int Id[100005];  
    10. int x[105],y[105];  
    11. bool vis[10005][205];  
    12. map<string,int> qwq;  
    13. void jt(int x,int y,int z)  
    14. {  
    15.     cnt++;  
    16.     nex[cnt]=las[x];  
    17.     las[x]=cnt;  
    18.     Arrive[cnt]=y;  
    19.     qz[cnt]=z;  
    20. }  
    21. queue<pair<int,int> >que;  
    22. int dp[10005];  
    23. int N,M;  
    24. void SPFA()  
    25. {  
    26.     while (!que.empty())  
    27.     {  
    28.         int u=que.front().first;  
    29.         int d=que.front().second;  
    30.         que.pop();  
    31.         vis[u][d]=false;  
    32.         for (int i=las[d];i;i=nex[i])  
    33.           {  
    34.             int v=Arrive[i];  
    35.             if (dis[u|Id[v]][v]>dis[u][d]+qz[i])  
    36.               {  
    37.                 dis[u|Id[v]][v]=dis[u][d]+qz[i];  
    38.                 if (!vis[u|Id[v]][v])  
    39.                   {  
    40.                     que.push(make_pair(u|Id[v],v));  
    41.                     vis[u|Id[v]][v]=true;  
    42.                    }  
    43.             }  
    44.           }  
    45.     }  
    46.     return;  
    47. }  
    48. int main()  
    49. {  
    50.     memset(dis,63,sizeof(dis));  
    51.     int INF=dis[0][0];  
    52.     scanf("%d%d",&N,&M);      
    53.     string s1;    
    54.     for (int i=1;i<=N;i++)  
    55.     {  
    56.         cin>>s1;  
    57.         qwq[s1]=i;  
    58.     }     
    59.     for (int i=1;i<=M;i++)  
    60.       {  
    61.         string s1,s2;  
    62.         int w;  
    63.         cin>>s1>>s2>>w;  
    64.         jt(qwq[s1],qwq[s2],w);  
    65.         jt(qwq[s2],qwq[s1],w);  
    66.       }  
    67.     
    68.     int cntt=0;  
    69.     string s2;  
    70.     for (int i=1;i<=4;i++)  
    71.       {  
    72.         int u,v;  
    73.         cin>>s1;  
    74.         u=qwq[s1];  
    75.         cin>>s2;  
    76.         v=qwq[s2];  
    77.         if (u==v)continue;  
    78.         if (bel[u]&&bel[v]){  
    79.             int upd=bel[v];if (bel[u]==bel[v])continue;  
    80.             for (int i=1;i<=Size[upd];i++)  
    81.             Lt[bel[u]][++Size[bel[u]]]=Lt[upd][i],bel[Lt[upd][i]]=bel[u];  
    82.             Size[upd]=0;  
    83.         }  
    84.         else if (bel[u]||bel[v]){  
    85.             if (bel[v])  
    86.               swap(u,v);  
    87.             bel[v]=bel[u];  
    88.             Lt[bel[u]][++Size[bel[u]]]=v;  
    89.         }  
    90.         else {  
    91.             bel[u]=bel[v]=++cntt;  
    92.             Lt[cntt][++Size[cntt]]=u;Lt[cntt][++Size[cntt]]=v;  
    93.         }  
    94.       }    
    95.     for (int i=1;i<=N;i++)  
    96.       if (bel[i])  
    97.         {  
    98.             Temp++;  
    99.             Id[i]=(1<<(Temp-1));  
    100.             dis[Id[i]][i]=0;  
    101.         }  
    102.     else dis[0][i]=0;  
    103.     int st=1<<Temp;  
    104.     for (int ST=0;ST<st;ST++)  
    105.     {  
    106.         for (int i=1;i<=N;i++)  
    107.             {  
    108.             for (int mst=(ST-1)&ST;mst;mst=(mst-1)&ST)  
    109.               dis[ST][i]=min(dis[ST][i],dis[mst|Id[i]][i]+dis[(ST-mst)|Id[i]][i]);  
    110.             if (dis[ST][i]<INF&&!vis[ST][i])  
    111.               que.push(make_pair(ST,i)),vis[ST][i]=true;  
    112.             }  
    113.         SPFA();  
    114.     }  
    115.     memset(dp,63,sizeof(dp));     
    116.     for (int i=1;i<=N;i++)  
    117.       for (int j=0;j<=st;j++)  
    118.         dp[j]=min(dis[j][i],dp[j]);  
    119.     
    120.     int Ncnt=cntt;  
    121.     cntt=0;  
    122.     for (int i=1;i<=Ncnt;i++)  
    123.       {  
    124.         if (Size[i])  
    125.           {  
    126.             cntt++;  
    127.             for (int j=1;j<=Size[i];j++)  
    128.               Bit[cntt]|=Id[Lt[i][j]];  
    129.             pd[Bit[cntt]]=true;  
    130.           }  
    131.       }  
    132.       dp[0]=0;  
    133.     for (int i=0;i<st;i++)  
    134.       for (int j=i;j;j=(j-1)&i)  
    135.           if (pd[j]&pd[i-j])  
    136.             pd[i]=true;  
    137.     for (int i=0;i<st;i++)  
    138.         if (pd[i])  
    139.          for (int j=i;j;j=(j-1)&i)  
    140.            if  (pd[j]) dp[i]=min(dp[i],dp[i-j]+dp[j]);  
    141.     printf("%d ",dp[st-1]);  
    142.     return 0;  
    143. }  
  • 相关阅读:
    [LeetCode] 75. 颜色分类(荷兰国旗)
    [LeetCode] 347. 前K个高频元素
    CMU-14445 数据库原理 汇总
    MIT-6.824 操作系统 汇总
    发布一个基于协程和事件循环的c++网络库
    记录一次gdb debug经历
    彻底弄懂UTF-8、Unicode、宽字符、locale
    CPU使用率原理及计算方式
    TCP使用注意事项总结
    STL-vector
  • 原文地址:https://www.cnblogs.com/si--nian/p/10640845.html
Copyright © 2011-2022 走看看