多維最短路。

注意點: 看代碼註釋

#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <cmath>
#include <iostream>
#include <set>
#include <vector>
#define INF 0x3f3f3f3f
using namespace std;
const int N=1e5+5;
typedef long long ll;
int n,m,s=1,t=2,cnt;
map<string,int> q;
int bin[205];
int a[205][205];
int dis[205],num[205],kill[205];
int cntn[205],vis[205];//記錄最快進攻的條數
int pre[205];
char ss[205][5];
void dij()
{
    for(int i=1; i<=n; i++)
        vis[i]=0,dis[i]=INF,cntn[i]=num[i]=0,kill[i]=0,pre[i]=-1;
    dis[s]=0,cntn[s]=1,num[s]=1;
    //如果起點不標記,那麼才能從s->p->i
    //路徑輸出纔能有S,而且這樣不需要初始化dis,kill,只需將起點那的屬性更改
    //如果起點標記了,那麼s->p這個路徑就沒有,只有p->i
    //導致殲敵人數少了bin[p]
    while(1)
    {
        int p=-1;
        for(int i=1; i<=n; i++)
        {
            if(vis[i]) continue;
            if(p==-1||(dis[i]<dis[p])||(dis[i]==dis[p]&&num[i]>num[p])||(dis[i]==dis[p]&&num[i]==num[p]&&kill[i]>kill[p]))
                p=i;
        }
        if(p==-1)return;
        vis[p]=1;
        for(int i=1; i<=n; i++)
        {
            if(vis[i])continue;
            if(dis[i]>dis[p]+a[p][i])
            {
                dis[i]=dis[p]+a[p][i];
                num[i]=num[p]+1;
                kill[i]=kill[p]+bin[i];
                cntn[i]=cntn[p];
                pre[i]=p;
            }
            else if(dis[i]==dis[p]+a[p][i]&&num[i]<num[p]+1)
            {
                num[i]=num[p]+1;
                kill[i]=kill[p]+bin[i];
                cntn[i]+=cntn[p];//
                pre[i]=p;
            }
            else if(dis[i]==dis[p]+a[p][i]&&num[i]==num[p]+1&&kill[i]<kill[p]+bin[i])
            {
                kill[i]=kill[p]+bin[i];
                cntn[i]+=cntn[p];//
                pre[i]=p;
            }
            else if(dis[i]==dis[p]+a[p][i])
                cntn[i]+=cntn[p];
        }
    }
}
void dfs(int x)
{
    if(x==s)
    {
        printf("%s",ss[s]);
        return;
    }
    dfs(pre[x]);
    printf("->%s",ss[x]);
}
int main()
{
    char u[5],v[5];
    scanf("%d%d%s%s",&n,&m,u,v);
    q[u]=1,strcpy(ss[1],u),q[v]=2,strcpy(ss[2],v);
    cnt=2;
    for(int i=1; i<=n; i++)
        for(int j=1; j<=n; j++)
            if(i==j) a[i][i]=0;
            else a[i][j]=INF;
    for(int i=0; i<n-1; i++)
    {
        int x;
        scanf("%s%d",u,&x);
        if(!q[u]) q[u]=++cnt,strcpy(ss[cnt],u);
        bin[q[u]]=x;
    }
    while(m--)
    {
        int w;
        scanf("%s%s%d",u,v,&w);
        int uu=q[u],vv=q[v];
        if(a[uu][vv]>w)
            a[uu][vv]=a[vv][uu]=w;
    }
    dij();
    dfs(t);
    puts("");
    printf("%d %d %d\n",cntn[t],dis[t],kill[t]);
}
發佈了177 篇原創文章 · 獲贊 85 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章