| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
Tips:这题有陷阱,可能存在比酋长高的等级(内有解决方法, 以及SPFA AC代码 16MS)所以要枚举最短路上的等级范围从[level[1]-m,level[1]]到[level[1],level[1]+m] !!
这其实还是符合逻辑的,比如酋长的曾祖父之类的咯~
附上SPFA AC代码 1164K 16MS:
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <vector>
#include <map>
#include <stack>
#include <queue>
#include <set>
#include <cmath>
#include <iomanip>
#include <algorithm>
using namespace std;
const int maxn=200;
const int INF=999999999;
struct Edge
{
int to,cost;
Edge *next;
Edge():to(0),cost(0),next(0){}
Edge(int TO,int COST,Edge *NEXT):to(TO),cost(COST),next(NEXT){}
};
Edge first[maxn];
Edge newEdge[maxn*maxn];
int cnt=0;
int m,n;
int level[maxn];
int vis[maxn];
int dist[maxn];
int _LEFT,_RIGHT;
int ans;
int addedge(int from,int to,int cost)
{
if(first[from].to==0)
{
first[from]=Edge(to,cost,0);
}
else
{
newEdge[++cnt]=first[from];
first[from]=Edge(to,cost,&newEdge[cnt]);
}
return 0;
}
int init()
{
cnt=0;
_LEFT=_RIGHT=0;
ans=INF;
memset(first,0,sizeof(first));
memset(newEdge,0,sizeof(newEdge));
memset(level,0,sizeof(level));
memset(vis,0,sizeof(vis));
scanf("%d%d",&m,&n);
int up;
int cost,alter,to;
for(int i=1;i<=n;i++)
{
scanf("%d%d%d",&cost,&level[i],&alter);
addedge(i,n+1,cost);
for(int j=1;j<=alter;j++)
{
scanf("%d%d",&to,&cost);
addedge(i,to,cost);
}
}
level[n+1]=level[1];
return 0;
}
int range(int x)
{
return x>=_LEFT&&x<=_RIGHT;
}
int SPFA(int v0,int vt)
{
queue <int> Q;
memset(vis,0,sizeof(vis));
for(int i=1;i<=n+1;i++)
{
dist[i]=INF;
}
dist[v0]=0;
vis[v0]=1;
Q.push(v0);
while(!Q.empty())
{
int now=Q.front();
Q.pop();
vis[now]=0;
for(Edge *p=&first[now];p!=0;p=p->next)
{
int to=p->to;
int cost=p->cost;
if(range(level[to]))
if(dist[to]>dist[now]+cost)
{
dist[to]=dist[now]+cost;
if(vis[to]==0)
{
vis[to]=1;
Q.push(to);
}
}
}
}
return dist[vt];
return 0;
}
int solve()
{
for(_LEFT=level[1]-m,_RIGHT=level[1];_LEFT<=level[1];_LEFT++,_RIGHT++)
ans=min(ans,SPFA(1,n+1));
printf("%d\n",ans);
return 0;
}
int main()
{
//freopen("1062.in","r",stdin);
//freopen("1062.out","w",stdout);
init();
solve();
return 0;
}
/*
Tips:这题有陷阱,可能存在比首长高的等级,所以要枚举最短路上的等级范围从[level[1]-m,level[1]]到[level[1],level[1]+m] !!
*/
Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator