POJ2240 SPFA判断正权环
题目分析
问你能否通过汇率是自己的这一种货币增加,把最短路改成最长路,负权环就会变成正权环
代码
#include<iostream>
#include<map>
#include<queue>
#include<vector>
#include<string>
#include<string.h>
using namespace std;
const int MAXN = 50;
const int INF = 0x3f3f3f;
struct Edge{
int v;
double val;
Edge(int v_,double val_){
v = v_;
val = val_;
}
};
int N,M,cntt = 0;
map<string,int> a;
vector<Edge> e[MAXN];
queue<int> q;
bool vis[MAXN];
int cnt[MAXN];
double dis[MAXN];
bool SPFA(){
memset(vis,0,sizeof(vis));
memset(cnt,0,sizeof(cnt));
memset(dis,0,sizeof(dis));
while(!q.empty()) q.pop();
q.push(0);
dis[0] = 1;
vis[0] = true;
cnt[0]++;
while(q.size()){
int f = q.front();
q.pop();
vis[f] = false;
cnt[f]++;
for(int i = 0;i < e[f].size();i++){
if(dis[f]*e[f][i].val>dis[e[f][i].v]){
dis[e[f][i].v] = dis[f]*e[f][i].val;
if(!vis[e[f][i].v]){
q.push(e[f][i].v);
vis[e[f][i].v] = true;
if(++cnt[e[f][i].v]>N) return false;
}
}
}
}
return true;
}
int main(){
while((cin>>N)&&N!=0){
cntt++;
a.clear();
for(int i = 0;i < MAXN;i++)
e[i].clear();
for(int i = 0;i < N;i++){
string tmp;
cin>>tmp;
a.insert(pair<string,int>(tmp,i));
}
cin>>M;
for(int i = 0;i < M;i++){
string tmp1,tmp2;
double cost;
cin>>tmp1>>cost>>tmp2;
map<string,int>::iterator it1 = a.find(tmp1);
map<string,int>::iterator it2 = a.find(tmp2);
e[it1->second].push_back(Edge(it2->second,cost));
}
if(SPFA()) cout<<"Case "<<cntt<<": No"<<endl;
else cout<<"Case "<<cntt<<": Yes"<<endl;
}
}
708K 797MS