您的位置:首页 > 其它

pku 3259(最短路径,spfa)

2010-05-02 08:57 531 查看
有n个农场,m条路径,w条虫洞路径。

随后输入m条路径,要处理双向边。然后跟w条虫洞路径,输入这个路径值时要取反。构图然后spfa判环。

#include <iostream>
#include <vector>
#include <queue>
using namespace std;
/*
传入源点s,n存储点的个数,用dis数组存下最短路径值
edge[i]存入与i相邻的点及其权值
返回值为true则无负环,为false则存在负环
*/
class node
{
public:
int v,w;
};
const int inf=0x7fffffff;
const int MAXN=600;
int numv,dis[MAXN];
bool visit[MAXN];
int time[MAXN],n,m,w;
vector<node> edge[MAXN];
bool spfa(int s)
{
int tmp,t,sz;
queue<int>	que;
memset(time,0,sizeof(time));
memset(visit,false,sizeof(visit));
for(int i=0;i<=n;++i)
dis[i] = inf;
dis[s] = 0;
que.push(s);
time[s]++;		//init
while(!que.empty())
{
tmp = que.front();
que.pop();
visit[tmp] = false;
sz=edge[tmp].size();
for(int i=0;i<sz;++i)
{
t = edge[tmp][i].w;
if(dis[edge[tmp][i].v] > dis[tmp]+t)
{
dis[edge[tmp][i].v] = dis[tmp] + t;
if(!visit[edge[tmp][i].v])	//若该点不在队列中,则入队,并修改相应的信息
{
visit[edge[tmp][i].v] = true;
time[edge[tmp][i].v]++;
if(time[edge[tmp][i].v] > n) return false;	//若一个点的引用次数大于n则证明有负环
que.push(edge[tmp][i].v);
}
}
}
if(dis[s]<0)	//判负环
return false;
}
return true;
}
int main()
{
int cas,s,e,t;
node tmp;
cin>>cas;
while(cas--)
{
cin>>n>>m>>w;
for(int i=1;i<=n;++i)
edge[i].clear();
while (m--)
{
cin>>s>>e>>t;
tmp.v=e;	tmp.w=t;
edge[s].push_back(tmp);
tmp.v=s;	tmp.w=t;
edge[e].push_back(tmp);	//处理双向边
}
while(w--)
{
cin>>s>>e>>t;
tmp.v=e;	tmp.w= -t;
edge[s].push_back(tmp);
}
if(spfa(1))	cout<<"NO"<<endl;
else cout<<"YES"<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: