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;
}