zoj3946 Highway Project(单源最短路径)

来源:互联网 发布:亲宝宝软件下载 编辑:程序博客网 时间:2024/06/08 06:15


题目传送门


题意:一个帝国有 n 个城市,可以在城市两两之间建立 m 条高速公路,建立  x,y

           之间的高速路需要时间 d(双向),花费为 c,最后建立完边后,使得首都 0

           号城市到各个城市的总时间最少的前提下,选择总时间最少的。



由于最后产生的图为一个树,因此对于每一个点,都可以假定出(面向起点的)有向边;

#include <iostream>#include <cstdio>#include <algorithm>#include <cmath>#include <cstring>#include <cstdlib>#include <string>#include <queue>#include <map>#include <vector>using namespace std;const int N=100005;const long long  MAX=1e15;long long dis[N];long long money[N];bool visited[N];vector<int> ve[N];       //邻接表表示;vector<int> vec[N];vector<int> vet[N];int start=0,n,m;void Spfa(){    for (int i=0; i<n; ++i)    {        dis[i] = MAX;        visited[i] = false;        money[i]=MAX;    }    queue<int> Q;    dis[start] = 0;    money[start]=0;    visited[start] = true;    Q.push(start);    while (!Q.empty()){        int temp = Q.front();        Q.pop();        for (int i=0; i<ve[temp].size(); ++i)        {            int qwe=ve[temp][i];            if (dis[temp] + vec[temp][i] <dis[qwe] )            {                dis[ve[temp][i]] = dis[temp] + vec[temp][i];                money[qwe]=vet[temp][i];                      //由于距离的更新,更新该点(与它前一个边的)的花费                if (!visited[qwe])                {                    Q.push(qwe);                    visited[qwe] = true;                }            }            else if(dis[temp] + vec[temp][i]==dis[qwe])            {                if(vet[temp][i]<money[qwe])                 //相同距离取最小的花费                {                    money[qwe]=vet[temp][i];                }            }        }        visited[temp] = false;    }};int main(){    int t,x,y,d,c;    scanf("%d",&t);    while(t--)    {        for(int i=0;i<n;i++)        {            ve[i].clear();            vec[i].clear();            vet[i].clear();        }        scanf("%d %d",&n,&m);        for(int i=1;i<=m;i++)        {            scanf("%d %d %d %d",&x,&y,&d,&c);            ve[x].push_back(y);            vec[x].push_back(d);            vet[x].push_back(c);            ve[y].push_back(x);            vec[y].push_back(d);            vet[y].push_back(c);        }        Spfa();        long long sum=0,sum1=0;        for(int i=0;i<n;i++)        {            sum+=dis[i];            sum1+=money[i];        }        cout<<sum<<" "<<sum1<<endl;    }    return 0;}


0 0
原创粉丝点击