Uvalive6885(最短路)

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=129723

题目大意:n个点,m条边,求出从0到n的最短距离,输出途中经过的边的权值和并乘以2(最短路不唯一且有重边)

题目思路:spfa求出最短路,在反向推回去

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <stack>
#include <cctype>
#include <queue>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <climits>
#define MOD 10000007
using namespace std;
#define N 10005
#define maxn 250050
#define inf 0x3f3f3f3f

int n,m,head[N],d[N],vis[N],ans;
struct Node{
    int to,v,next;
}node[maxn<<1]; ///因为是双向边,所以要开2倍
int n_cnt;

inline void add(int x,int y,int v)
{
    node[n_cnt].v=v;
    node[n_cnt].to=y;
    node[n_cnt].next=head[x];
    head[x]=n_cnt++;
}

void init()
{
    memset(d,inf,sizeof(d));        ///保存最短距离
    memset(head,-1,sizeof(head));   ///边的头结点
    memset(vis,0,sizeof(vis));
    n_cnt=ans=0;
}

void spfa()
{
    queue<int>q;
    d[0]=0;
    q.push(0);
    while(!q.empty())
    {
        int u=q.front(); q.pop();
        vis[u]=0;
        for(int i=head[u]; i+1; i=node[i].next)
        {
            int pos=node[i].to;
            if(d[pos]>d[u]+node[i].v)
            {
                d[pos]=d[u]+node[i].v;
                if(!vis[pos])
                {
                    q.push(pos);
                    vis[pos]=1;
                }
            }
        }
    }
}

void _solve()
{
    queue<int>q;
    q.push(n-1);
    int i;
    memset(vis,0,sizeof(vis));
    vis[n-1]=1;
    while(!q.empty())
    {
        int u=q.front();q.pop();
        for(i=head[u]; i+1; i=node[i].next)
        {
            int pos=node[i].to;
            if(d[pos]+node[i].v==d[u])  ///如果从pos->u的距离满足条件,则符合题意
            {                           ///满足的是最短路条件
                ans+=node[i].v;
                if(!vis[pos])
                {
                    vis[pos]=1;
                    q.push(pos);
                }
            }
        }
    }
    printf("%d\n",ans<<1);
}

int main()
{
    int i,j,x,y,v;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        init();
        for(i=0; i<m; ++i)
        {
            scanf("%d%d%d",&x,&y,&v);
            add(x,y,v);
            add(y,x,v);
        }
        spfa();
        _solve();
    }
    return 0;
}

 

posted @ 2016-04-04 18:31  Kurokey  阅读(153)  评论(0编辑  收藏  举报