现在的位置: 首页 > 综合 > 正文

BUPTOJ 1501

2013年10月04日 ⁄ 综合 ⁄ 共 1471字 ⁄ 字号 评论关闭

今天北邮校赛的一道题,最短路。

一开始的思路是1000个点都做一次SPFA,然后找出到询问值的最短路,但是T到死。

后来想了一下,发现其实可以将1000个点都指向一个超级源点,然后由该点出发开始搜,只需一遍,最后输出结果就可以了。

今天在这题上浪费了太多的时间,发挥的不是很好=。=加油吧。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstring>
#include <queue>
#include <set>
#include <vector>
#include <stack>
#include <map>
#include <iomanip>
#define PI acos(-1.0)
#define Max 2005
#define inf 1<<28
#define LL(x) (x<<1)
#define RR(x) (x<<1|1)
#define FOR(i,s,t) for(int i=(s);i<=(t);++i)
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
#define mp(a,b) make_pair(a,b)
using namespace std;

int head[10005];
struct kdq
{
    int v,val,next;
}edge[1000005 * 2];
int num = 0;
int n , m;
void add(int s,int e,int val)
{
    edge[num].v = s;
    edge[num].val = val;
    edge[num].next = head[e];
    head[e] = num ++;

    edge[num].v = e;
    edge[num].val = val;
    edge[num].next = head[s];
    head[s] = num ++;
}
int dis[10005];
void init()
{
    mem(head,-1);
    for (int i = 0 ;i <= n ;i ++)
    dis[i] = inf;
    num = 0;
}
bool vis[10005];
int qu[10000005];
void spfa(int s)
{
    int nn = 1, cn = 0;
    qu[0] = s ;
    vis[s] = 1;
    dis[s] = 0;
    while(nn > cn)
    {
        int temp = qu[cn ++];
        vis[temp] = 0;
        for (int i = head[temp] ;i != -1 ;i = edge[i].next)
        {
            int t = edge[i].v;
            int tt = edge[i].val;
            if(dis[t] > dis[temp] + tt)
            {
                dis[t] = dis[temp] + tt ;
                if(!vis[t])
                {
                    vis[t] = 1;
                    qu[nn ++] = t;
                }
            }
        }
    }
}
int main()
{
    int T;
    cin >> T;
    while ( T -- )
    {
        cin >> n >> m ;
        init();
        for (int i = 0 ;i < m ;i ++)
        {
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            add(a,b,c);
        }
        int S ;
        cin >> S ;
        for(int i = 0 ; i < S ; i ++)//把起点全部和超级源点连起来,就是0.
        {
            int dd;
            scanf("%d",&dd);
            add(0,dd,0);
        }
        int E;
        spfa(0);
        cin >> E;
        while( E -- )
        {
            int e;
            cin >>e;
            int ans = dis[e];
            if(ans == inf)
            ans = -1;
            cout <<ans<<endl;
        }
        cout <<endl;
    }
    return 0;
}

抱歉!评论已关闭.