首页 > 其他 > 详细

NYOJ 973 天下第一

时间:2015-04-21 18:01:18      阅读:128      评论:0      收藏:0      [点我收藏+]

题目连接:http://acm.nyist.net/JudgeOnline/problem.php?pid=973

算法分析:

spfa+负环判定

在传功的过程中如果因为f<1导致逐渐变小,那么即可以负环判定

#include <iostream>
#include<cstdio>
#include <cstdlib>
#include <queue>
#include <vector>
using namespace std;
 
const int MAXN=505;
const int INF=0x7FFFFFFF;
 
struct edge
{
    int to;
	double weight;
};
 
vector<edge> adjmap[MAXN];//邻接表
bool in_queue[MAXN];//顶点是否在队列中
int in_sum[MAXN];//顶点入队次数
double dist[MAXN];//源点到各点的最短路径
int nodesum;//顶点数
int edgesum;//边数
 
bool SPFA(int source)
{
    queue<int> dq;
    int i,j,x,to;
    for(i=1;i<=nodesum;i++)
    {
        in_sum[i]=0;
        in_queue[i]=false;
        dist[i]=0;
    }
    dq.push(source);
    in_sum[source]++;
    dist[source]=1.0;
    in_queue[source]=true;
 
    while(!dq.empty())
    {
        x=dq.front();
        dq.pop();
        in_queue[x]=false;
        for(i=0;i<adjmap[x].size();i++)
        {
        	double f=adjmap[x][i].weight;
            to=adjmap[x][i].to;
            if(dist[to]-dist[x]*f<0.01)
            {
                dist[to]=dist[x]*f;
                if(!in_queue[to])
                {
                	dq.push(to);
                    in_queue[to]=true;
                    if(++in_sum[to]>=nodesum) return true;

                }
            }
        }
    }
    return false;
}
 
int main()
{
    int n,i,s,e;
	double w;
    scanf("%d",&n);
    while(n--){
    edge temp;
    scanf("%d%d",&nodesum,&edgesum);
    for(i=1;i<=nodesum;i++)
    adjmap[i].clear();//清空邻接表
    for(i=1;i<=edgesum;i++)
    {
        scanf("%d%lf%d",&s,&w,&e);
        temp.to=e;
        temp.weight=w;
        adjmap[s].push_back(temp);
    }
	if(SPFA(1))
    cout<<"Yes"<<endl;
	else 
	cout<<"No"<<endl;
	}
    return 0;
}


NYOJ 973 天下第一

原文:http://blog.csdn.net/u014492609/article/details/45173765

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!