POJ 1511 Invitation Cards(双向最短路)

【题目链接】
http://poj.org/problem?id=1511

题目意思

给n个点,m条有向边。问你从1到其他n-1各点的最短路和加上从n-1各点到1的最短路。

解题思路

因为是有向边而且一次终点在1,一次起点在1,所以只要跑一遍正的图在跑遍反的地图,总和就是要的答案。
坑点在于数据比较大总和要用long long,邻接表开两个时间就会wa,要用优先队列优化。

代码部分


#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <string.h>
#include <queue>
#include <string>
#include <map>
using namespace std;
#define LL long long
#define inf 0x3f3f3f3f
const int N = 1e6+5;
LL dis[N];   ///存储正向最短路 
int vis[N];  ///记录是否在队列 
int k,n;
struct node
{
    int v;
    LL w;
    friend bool operator < (node a,node b)  
    {
        return a.w>b.w;
    }
}s;
struct edge
{
    int u,v,w;
}eg[N];
vector<vector<node> >m(N);
void init ()
{
    for (int i = 1; i <= n; i++)
    {
        dis[i] = inf;
        vis[i] = 0;
    }
}
node add (int v,LL w) ///转换成node类型 
{
    node t;
    t.v = v;
    t.w = w;
    return t;
}
void spfa()
{
    init();
    priority_queue<node>q;
    q.push(add(1,0));
    vis[1] = 1;
    dis[1] = 0;
    while (!q.empty())
    {
        node t = q.top();
        q.pop();
        for (int i = 0; i < m[t.v].size();i++)
        {
            s = m[t.v][i];
            if (dis[s.v] > dis[t.v]+s.w)  ///松弛 
            {
                dis[s.v] = dis[t.v]+s.w;
                if (!vis[s.v])   ///判断是否在队列 
                {
                    q.push(add(s.v,dis[s.v]));
                    vis[s.v] = 1;
                }
            }
        }
        vis[t.v] = 0;
    }
}
int main()
{
    int t;
    scanf("%d",&t);
    while (t--)
    {
        LL ans = 0;
        scanf("%d %d",&n,&k);
        for (int i = 1; i<= n; i++)
        {
            m[i].clear();
        }
        for(int i =0; i < k;i++)
        {
            int v,u,w;
            scanf("%d %d %d",&eg[i].u,&eg[i].v,&eg[i].w);
            m[eg[i].u].push_back(add(eg[i].v,eg[i].w));
        }
        spfa();
        for (int i = 1;i<= n ;i++)  /// 求和并清除图 
        {  
            ans += dis[i];
            m[i].clear();
        } 
        for (int i = 0; i <= k; i++)  ///构造方向图 
        {
            m[eg[i].v].push_back(add(eg[i].u,eg[i].w));
        }
        spfa();
        for (int i = 1; i <= n; i++)
             ans += dis[i];
        printf("%lld\n",ans);
    }
    return 0;
} 

猜你喜欢

转载自blog.csdn.net/pashuihou/article/details/80084047