USACO/Sweet Butter

USACO/Sweet Butter

Posted by dym on May 20, 2014

本文迁移自老博客,原始链接为 https://seven.blog.ustc.edu.cn/usacosweet-butter/

给定一个图,求图上所有点中到几个给定点的距离和的最小值。 解法:邻接表实现的spfa

#include<iostream>
#include<algorithm>
#include<fstream>
#include<stdio.h>
#include<string.h>
#include<queue>;
using namespace std;

ofstream fout ("butter.out");
ifstream fin ("butter.in");
#define INF 1000000050
int niu[501];

bool vis[801];
struct no
{
     int u,v,nxt;
}node[10005];
int edge[10005];
int inq[10005];
int n,p,q;
long long sum,dis[10005];
int a,b,d,c;
void init()
{
     for(int i=1;i<=2*c;i++)
     {
          edge[i]=0;
     }
}
void spfa(no node[] ,int edge[] , int sou)
{
     int i;
     for(int j=1;j<=p;j++)
          inq[j]=false;
     queue<int> que;
     que.push(sou);
     inq[sou] = true;
     for (i=1; i<=p; i++)
     {
          dis[i] = INF;
     }
     dis[sou] = 0;
     while (!que.empty())
     {
          int s = que.front();
          que.pop();
          inq[s] = false;
          int p=edge[s];
          while( p!=0)
          {
               int v=node[p].v;
               int u=node[p].u;
               if (dis[v] > dis[s] + u)
               {
                    dis[v] = dis[s] + u;
                    if (!inq[v])
                    {
                         que.push(v);
                         inq[v] = true;
                    }
               }
               p=node[p].nxt;
          }
     }
}
int main()
{
    fin>>n>>p>>c;
    init();
    for(int i = 0 ; i < n ;i++)
        fin>>niu[i];
    for(int i=1; i <= 2 * c;)
    {
        fin>>a>>b>>d;
        node[i].v=b;
        node[i].u=d;
        node[i].nxt=edge[a];
        edge[a]=i++;

        node[i].v=a;
        node[i].u=d;
        node[i].nxt=edge[b];
        edge[b]=i++;
    }
    int Min = INF;
    for(int i = 1; i <= p; i ++)
    {
        sum = 0;
        spfa(node , edge , i);
        for(int j = 0 ; j < n ; j++)
        {
            sum += dis[niu[j]];
        }
        if(Min > sum)
            Min = sum;
    }
    fout<<Min<<endl;
    return 0;
}