CSU1978-LXX的图论题-SPFA判环

来源:互联网 发布:vs怎么编译c语言 编辑:程序博客网 时间:2024/06/05 03:34

CSU1978-LXX的图论题-SPFA判环

Description

由于lxx的图论和数据结构太弱了,大佬Z决定为lxx补一补。于是大佬Z为lxx出了一道题目,题目如下:给出一张有向图,图中有n个点,m条边,每条边上都有一个权值w,问图中是否存在满足以下条件的点i,j,…p使得不等式w[i][j] * w[j][k] * …. * w[p][i]<1成立。奈何lxx太弱了,他决定寻求你的帮助。

Input

多组输入,以文件结尾。第一行两个整数n( 1<=n<=500 ),m( 1<=m<=n*(n-1)/2 ),接下来m行,每行3个数x,y,z,(x≠y):表示x到y有一条边,权值为z(0

Output

如果存在满足题目所描述的式子,输出“YES”,否则输出“NO”。

Sample Input

2 21 2 0.92 1 1.26 41 2 0.12 4 0.84 1 124 1 15

Sample Output

NOYES

Hint

点的编号为1~n


思路

就是SPFA判环嘛

首先把式子取个对数从乘法变成加法,于是就是裸的判负环了

但是我比赛的时候没A,不知道乘法会精度丢失,毕竟500个……

AC代码

/************************************** *Source            : CSU1978 *Knowledge Point   : SPFA_PENDING_CYCLE *Author            : CSUzick**************************************/#include <cstdio>#include <iomanip>#include <cstring>#include <iostream>#include <stack>#include <vector>#include <queue>#include <cctype>#include <cmath>#include <algorithm>#include <set>#include <bitset>#include <map>#define LL long long#define mk(a,b) make_pair(a,b)#define ULL unsigned long long#define mem(a,n) memset(a,n,sizeof(a))#define fread freopen("in.txt","r",stdin)#define fwrite freopen("out.txt","w",stdout)#define N 550#define INF 0x3f3f3f3f#define eps 1e-12using namespace std;struct Edge{    int from,to;    double dist;    Edge(int u,int v,double d):from(u),to(v),dist(d){};};struct SPFA{    vector<Edge> edges;    vector<int> G[N];    bool inque[N];    double d[N];    int cnt[N];    int n,m;    void init(int n){        this->n=n;        for(int i=0;i<=n;++i){            G[i].clear();        }        edges.clear();    }    void AddEdge(int from,int to,double dist){        edges.push_back(Edge(from,to,dist));        m=edges.size();        G[from].push_back(m-1);    }    bool spfa(){        queue<int> que;        memset(inque,0,sizeof(inque));        memset(cnt,0,sizeof(cnt));        for(int i=0;i<=n;++i){            que.push(i);             d[i]=0;            inque[i]=false;        }        while(!que.empty()){            int temp=que.front();            if(cnt[temp]==n){                return true;            }            que.pop();            inque[temp]=false;            for(int i=0;i<G[temp].size();++i){                Edge &e=edges[G[temp][i]];                if(d[e.to]-d[temp]-e.dist>eps){                    d[e.to]=d[temp]+e.dist;                    if(!inque[e.to]){                        que.push(e.to);                        inque[e.to]=true;                        if(++cnt[e.to]>=n)  return true;                    }                }            }        }        return false;    }};SPFA SMF;int main(){    int n,m,u,v;    double c;    while(~scanf("%d%d",&n,&m)){        SMF.init(n);        while(m--){            scanf("%d%d%lf",&u,&v,&c);            SMF.AddEdge(u,v,log2(c));        }        if(SMF.spfa()){            printf("YES\n");        }else{            printf("NO\n");        }    }    return 0;}
原创粉丝点击