标签:
题意:有N个房间,刚开始你位于1号房间,有100的能量值,你要到达N号房间,每两个房间之间有单向门相连接,你到达某个房间可以加上该房间的能量值,如果你在未到达N号房间之前能量值耗尽,则死亡,否则胜利。
解析:spfa,设power[]是从1到达某个点的能量值,如果power[v]>power[u]+energy[v],(power[1]设置为100,其他设置为0)所以power[]不会出现负数的情况,由于可能出现负圈的情况,所以要设置spfa次数上限,我设的10000,应该足够了,设置小了会wa。可以自己尝试一下。
代码如下:
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<set>
#include<map>
#include<queue>
#include<vector>
#include<iterator>
#include<utility>
#include<sstream>
#include<iostream>
#include<cmath>
#include<stack>
using namespace std;
const int INF=1000000007;
const double eps=0.00000001;
vector<int> G[105];
int N;
int energy[105],power[105]; // energy是房间的能量值,power是从1到达某个房间的能量值
bool vis[105];
int cnt[105]; // 访问次数
bool spfa()
{
memset(vis,false,sizeof(vis));
memset(power,0,sizeof(power));
memset(cnt,0,sizeof(cnt));
power[1]=100;
vis[1]=true;
queue<int> que;
que.push(1);
while(!que.empty())
{
int now=que.front(); que.pop();
vis[now]=false;
for(int i=0;i<G[now].size();i++)
{
int to=G[now][i];
if(power[now]+energy[to]>power[to]&&cnt[to]<=10000) // 次数上限为10000
{
power[to]=power[now]+energy[to]; // 更新
cnt[to]++;
if(!vis[to])
{
vis[to]=true;
que.push(to);
}
}
}
if(power[N]>0) return true; //为真
}
return false;
}
int main()
{
while(cin>>N)
{
if(N==-1) break;
for(int i=0;i<=N;i++) G[i].clear();
for(int i=1;i<=N;i++)
{
int k;
scanf("%d%d",&energy[i],&k);
for(int j=1