BUPT Summer Journey #test8 B

 

B. 小妹妹送快递 2014新生暑假个人排位赛08

时间限制 1000 ms     内存限制65536 KB    

题目描述

Mays王国的女王大人每天过着自由自在的生活,她最大的乐趣就是给邻国的帅气王子写信。但是最近,Mays王国的叔叔们变得很无聊,他们知道女王大人每次都把信委托给皇家小妹妹快递公司的小妹妹们,于是叔叔们给每一条路都设立了路障,只有小妹妹们给他们表演节目才会让小妹妹们过去。
在每一个路障,都有不同数量的叔叔,只有表演的小妹妹的数量不少与叔叔的数量的时候叔叔才会放她们过去。
为了节省开销,小妹妹快递公司希望派最少的小妹妹把女王大人的信件送到。请你告诉他们需要派几个小妹妹。

输入格式

输入第一行为数据组数T(T<=10),接下来T组数据,每组第一行为n,m,,2<=n<=10000,1<=m<=100000,表示Mays王国的道路由n个节点组成,接下来m行,每行一组u,v,c表示连接节点u,v的一条无向道路,且路障上有c个叔叔,1<=u,v<=n,0<=c<=100。女王大人和皇家小妹妹快递公司都在节点1,帅气的邻国王子住在节点n。

输出格式

每组数据输出一个数字,表示小妹妹快递公司最少需要派出的小妹妹数量。如果无论派出多少小妹妹都无法把信送到帅气的邻国王子手里,输出"shimatta!"。

输入样例

1
3 3
1 2 1
2 3 1
1 3 3

输出样例

1

 

思路:考察spfa的细节,即利用当前最大的边更新的时候考察当前的更新点的最大和到其余顶点的最大C的最大值若小于新节点则更新。注意若没有小妹妹则需要一个小妹妹送过去。

代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#define maxn 40005
#define maxm 400005
//#define LOCAL
using namespace std;
struct Edge
{
    int from,to,next,v;
}e[maxm];
int n,m,cnt,s,maxx;
int h[maxn],vis[maxn],dist[maxn],q[4*maxm];
void AddEdge(int x,int y,int v)
{
    cnt++;e[cnt].from=x;e[cnt].to=y;e[cnt].v=v;e[cnt].next=h[x];h[x]=cnt;
}
void SPFA()
{
    for(int i=1;i<=n;i++)dist[i]=200000000;
    int head=0,tail=0;
    dist[s]=-100;vis[s]=1;tail++;q[tail]=s;
    while(head<tail)
    {
        head++;
        int u=q[head];
        for(int i=h[u];i!=-1;i=e[i].next)
        {
            int v=e[i].to;
            if(max(e[i].v,dist[u])<dist[v])
            {
                dist[v]=max(e[i].v,dist[u]);
                if(!vis[v])
                {
                    vis[v]=1;tail++;q[tail]=v;
                }
            }
        }
        vis[u]=0;
    }
 
}
int main()
{
    #ifdef LOCAL
    freopen("input.txt","r",stdin);
    #endif // LOCAL
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        memset(h,-1,sizeof(h));
        memset(vis,0,sizeof(vis));
        int x,y,v;
        cnt=0;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&x,&y,&v);
            AddEdge(x,y,v);
            AddEdge(y,x,v);
            if(maxx<v)maxx=v;
        }
        //for(int i=1;i<=cnt;i++)printf("x=%d y=%d v=%d\n",e[i].from,e[i].to,e[i].v);
        s=1;
        SPFA();
        if(dist[n]!=200000000)
        {
            if(dist[n]==0)printf("1\n");
            else printf("%d\n",dist[n]);
        }
        else printf("shimatta!\n");
    }
    return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值