Castle in the Sky

Insert picture description here
ps: The town here is the city, n cities, the 5 towns in the title are useless.
Input:
5 5
Orz
Ada Aed 5
Orz Ada 6
Apq Aed 8
Akk Apq 12
Aed Orz 3

Output:
28
Insert picture description here
Idea: Core: Minimum Spanning Tree
. If you go back, the cost is 0. Find the minimum cost for traversing all cities. Since the cost is 0, it is equivalent to no-cost backtracking, and only the minimum spanning tree of the graph is required.
The city name is stored in a map, and it is more comfortable to convert a string to a number.

//
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
map <string ,int> mm; //城市名和int对应
int head[5010]; 
int tot=0;
int cnt=0;
ll dis[5010];//存每个点离树的最近距离
int v[5010]; //最近距离是否已确定
int st; //起点
ll res=0; //结果
struct ty
{
    
    
    int t,next;
    int l;
    bool operator < (const ty &b ) const //prim算法,将花费最小的边存前面
    {
    
    
        return l > b.l;
    }
}edge[4000010];
priority_queue <ty > q;
void addedge(int x, int y,int z)
{
    
    
    edge[++tot].t=y;
    edge[tot].l=z;
    edge[tot].next=head[x];
    head[x]=tot;
}
void prim()
{
    
    
    ty ty3;
    ty3.l=0;
    ty3.t=st;
    q.push(ty3);
    dis[st]=0;
    while( !q.empty() )
    {
    
    
        ty ty1=q.top();
        q.pop();
        if( v[ty1.t] )  continue;
        v[ty1.t]=1;
        res+=ty1.l;
        dis[ty1.t]=0;
        for(int i=head[ty1.t] ;i!=-1 ;i=edge[i].next)
        {
    
    
            int u=edge[i].t;
            if(edge[i].l <dis[u] )
            {
    
    
                dis[u] =edge[i].l;
                ty ty2;
                ty2.t=u;
                ty2.l=dis[u];
                q.push(ty2);
            }
        }
    }
}
int main()
{
    
    
    ios::sync_with_stdio(false );
//    cin.tie(0);cout.tie(0);
    int n,qq;
    while(    cin>>n>>qq)
    {
    
    
        //初始化各种数据和结构
        memset(dis,0x3f,sizeof(dis));
        memset(head,-1,sizeof(head));
        memset(edge,-1,sizeof(edge));
        memset(v,0,sizeof(v));
        tot=0,cnt=0,res=0;
        mm.clear();
        while(!q.empty() )  q.pop();
        int flag=0;

        //输入起点
        string o;
        cin>>o;
        for(int i=1 ;i<=qq; i++)
        {
    
    
            string s1,s2;
            int z;
            cin>>s1>>s2;
            cin>>z;
            //将城市名转为编号存图
            if( mm.find(s1) ==mm.end() )    mm[s1]=++cnt;
            if( mm.find(s2) ==mm.end() )    mm[s2]=++cnt;
            int x=mm[s1];
            int y=mm[s2];
            addedge(x,y,z);
            addedge(y,x,z);
        }
        st=mm[o];//找起点
        
        if( n==1 ) {
    
    cout<<0<<"\n";continue;} //n==1特判
        //prim算法求最小生成树
        prim();
        //判是不是每个城市都走过了
        for(int i=1 ;i<=n ;i++)
        {
    
    
            if( !v[i] ) {
    
    cout<<"No!\n";flag=1;break;}
        }
        if(flag)    continue;
        cout<<res<<endl;
    }
}

Guess you like

Origin blog.csdn.net/m0_53688600/article/details/114051331
sky