2012北邮腾讯创新俱乐部热身赛 B

B是很水很水的最短路,只要注意重边就ok了~~好坑爹啊,害我wa了那么多次!!!


BGraph
Accept:10Submit:54
Time Limit:1500MSMemory Limit:65536KB

Description

Saerdna likes travelling, but he can not afford the GPS. He only has a broken map with him. However, he could only find out the approximate locations of the tourist attractions with the map which is too dilapidated. After arriving there, he could ask for the specific destination. Can you help him?

Input

The first line of the input is an integer T(T<=10), which represents that there are T test cases.

Each test case starts with two integers R, U(U<=20) representing the number of points and the number of connected blocks in the map.

And then U blocks follow.

The first line of each block contains two integers K(K<=20), I(I<=K^2), which represent the number of points and the number of edges in each connected block.

This is followed by I lines, each line contains three integers a, b, c, which represents that there is an edge between a and b with the length c(c<=100000).

After the U blocks, there is an integer Q (Q<=5000), for Q queries.

Next there are Q lines; each line has one of the two forms as follow:

add a b c

query a b

Output

Each case starts with Case :S (S represents for the case number).

Then for each query, print the shortest path between a and b, if there is no path, print -1.Print each answer in a line.

Sample input

1

4 2

2 1

0 1 1

2 1

2 3 1

3

query 0 3

add 1 2 2

query 0 3

Sample output

Case :1

-1

4

Hints:

We guarantee that a and b are not in the same connected block when add edge.

Point numbers in the same connected block are continues.


#include<iostream>
#include<vector>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<stack>
#include<string>
#include<map>
#include<set>
#include<cmath>
#include<cassert>
#include<cstring>
#include<iomanip>
using namespace std;

#ifdef _WIN32
#define i64 __int64
#define out64 "%I64d\n"
#define in64 "%I64d"
#else
#define i64 long long
#define out64 "%lld\n"
#define in64 "%lld"
#endif

#define FOR(i,a,b)      for( int i = (a) ; i <= (b) ; i ++)
#define FF(i,a)         for( int i = 0 ; i < (a) ; i ++)
#define FFD(i,a)        for( int i = (a)-1 ; i >= 0 ; i --)
#define S64(a)          scanf(in64,&a)
#define SS(a)           scanf("%d",&a)
#define LL(a)           ((a)<<1)
#define RR(a)           (((a)<<1)+1)
#define SZ(a)           ((int)a.size())
#define PP(n,m,a)		puts("---");FF(i,n){FF(j,m)cout << a[i][j] << ' ';puts("");}
#define pb              push_back
#define CL(Q)           while(!Q.empty())Q.pop()
#define MM(name,what)   memset(name,what,sizeof(name))
#define read            freopen("in.txt","r",stdin)
#define write           freopen("out.txt","w",stdout)

const int inf = 0x3f3f3f3f;
const i64 inf64 = 0x3f3f3f3f3f3f3f3fLL;
const double oo = 10e9;
const double eps = 10e-10;
const double pi = acos(-1.0);
const int maxn = 1111;

struct zz
{
    int from;
    int to;
    int cost;
}zx;

vector<zz>g[maxn];
queue<int>q;
bool inq[maxn];
i64 way[maxn];


int T,R,U,qq;
int num[111],I;
int f[maxn];
int x,y,l;
char s[11];

int find(int now)
{
    if(now!=f[now])
    {
        return f[now] = find(f[now]);
    }
    return now;
}

i64 spfa(int from,int end)
{
    while(!q.empty())
    {
        q.pop();
    }
    MM(inq,false);
    FF(i,maxn) way[i] = inf64;
    inq[from] = true;
    way[from] = 0;
    q.push(from);
    i64 now,to,cost;
    while(!q.empty())
    {
        now = q.front();
        q.pop();
        FF(i,g[now].size())
        {
            to = g[now][i].to;
            cost = g[now][i].cost + way[now];
            if(cost < way[to] )
            {
                way[to] = cost;
                if(!inq[to])
                {
                    inq[to] =true;
                    q.push(to);
                }
            }
        }
        inq[now] = false;
    }
    return way[end];
}

int main()
{
    cin>>T;
    for(int tt=1;tt<=T;tt++)
    {
        printf("Case :%d\n",tt);
        FF(i,maxn) g[i].clear();
        FF(i,maxn) f[i]=i;
        cin>>R>>U;
        for(int i=1;i<=U;i++)
        {
            cin>>num[i]>>I;
            for(int j=1;j<=I;j++)
            {
                SS(x);
                SS(y);
                SS(l);
                zx.from = x;
                zx.to = y;
                zx.cost = l;
                    g[zx.from].pb(zx);
                    swap(zx.from,zx.to);
                    g[zx.from].pb(zx);
                f[find(x)] = find(y);
            }
        }
        cin>>qq;
        for(int i=1;i<=qq;i++)
        {
            scanf("%s",s);
            if(s[0] == 'q')
            {
                SS(x);
                SS(y);
                if(x==y)
                {
                    printf("0\n");
                    continue;
                }
                if(find(x) == find(y))
                {
                    i64 temp =spfa(x,y);
                    if(temp == inf64)
                    {
                        printf("-1\n");
                    }
                    else
                    {
                        cout<<temp<<endl;
                    }
                }
                else
                {
                    printf("-1\n");
                }
            }
            else if(s[0] == 'a')
            {
                SS(x);
                SS(y);
                SS(l);
                f[find(x)] = find(y);
                zx.from = x;
                zx.to = y;
                zx.cost = l;
                    g[zx.from].pb(zx);
                    swap(zx.from,zx.to);
                    g[zx.from].pb(zx);
            }
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值