洛谷1828甘いバター


タイトルの説明
農夫のジョンは、全ウィスコンシン州で最も甘いバターを作る方法:砂糖を発見した.砂糖を牧場に置くと、N(1<=N<=500)の乳牛が舐めに来ることを知っていて、値段が売れる超甘いバターを作ることができます.もちろん、彼は乳牛に追加の費用を払うことになります.
農夫のジョンはずるい.以前のPavlovのように、彼はこれらの乳牛を訓練して、ベルが聞こえたときに特定の牧場に行くことができることを知っています.彼は砂糖をそこに置いて午後ベルを鳴らすつもりで、夜に乳を搾ることができます.
農夫のジョンは乳牛がそれぞれ好きな牧場にいることを知っている(1つの牧場には牛が1頭しかいないとは限らない).各牛がいる牧場と牧場の間のルートを与えて、すべての牛を到着させる道のりと最も短い牧場を見つけます(彼は砂糖をそこに置きます)
にゅうしゅつりょくけいしき
入力フォーマット:1行目:3個数:乳牛数N、牧場数(2<=P<=800)、牧場間道数C(1<=C<=1450)
2行目からN+1行目:1からN頭の乳牛がいる牧場番号
N+2行目からN+C+1行目:行ごとに3つの数がある:つながっている牧場A、B、2つの牧場間距離D(1<=D<=255)、もちろん、接続は双方向である
出力フォーマット:乳牛が歩かなければならない最小距離と
入出力サンプル
入力サンプル#1:コピー3 4 5 2 3 4 1 1 1 3 5 2 3 7 2 4 3 4 5出力サンプル#1:コピー8説明
{サンプルパターン
      P2  

P 1@–1-@C 1||5 7 3||C 3 C 2@–5-@P 3 P 4}{説明:
4番牧場に置くのが一番いいです
}
この問題はspfaと隣接表を使っていて、Floyd+最適化もできるようです.の構想は1点ごとに1回遍歴して、spfaは最小値を求めて、1つの牧場は1頭の牛だけではないかもしれません.ここに穴があいた.
#include 
using namespace std;
const int maxn=3005;
int n,p,c,head[maxn],cnt,q[maxn],sum,ans=0x3f3f3f3f,dis[maxn],cow[maxn];
bool vis[maxn];
struct Edge{
    int next,to,w;
}edge[maxn];
inline void add(int bg,int ed,int v){  //      
    edge[++cnt].to=ed;
    edge[cnt].w=v;
    edge[cnt].next=head[bg];
    head[bg]=cnt;
}
inline void spfa(int s){  //spfa 
    sum=0;
    int u,h=0,t=1;
    dis[s]=0;
    vis[s]=1;
    q[1]=s;
    while(hq[++h];
        vis[u]=0;
        for(register int i=head[u];i;i=edge[i].next)
            if(dis[edge[i].to]>dis[u]+edge[i].w){ 
                dis[edge[i].to]=dis[u]+edge[i].w;
                if(!vis[edge[i].to]){
                    vis[edge[i].to]=1;
                    q[++t]=edge[i].to;
                }
            } 
    }
    for(register int i=1;i<=p;i++){
        if(cow[i])
            sum+=dis[i]*cow[i];
    }
    ans=min(ans,sum);
}
int main(){
    scanf("%d%d%d",&n,&p,&c);
    for(register int i=1;i<=n;i++){
        int x;
        scanf("%d",&x);
        cow[x]++;
    }
    for(register int i=1;i<=c;i++){
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);
        add(y,x,z);
    }
    for(register int i=1;i<=p;i++){
        memset(dis,0x3f,sizeof(dis));
        memset(vis,0,sizeof(vis));
        spfa(i);
    }
    printf("%d",ans);
    return 0;
}