NYOJ 973 天下第一

来源:互联网 发布:c语言的科学与艺术答案 编辑:程序博客网 时间:2024/04/30 18:55

题目连接: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;}


0 1
原创粉丝点击