1978: LXX的图论题
Time Limit: 1 Sec Memory Limit: 128 Mb Submitted: 22 Solved: 9
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<z<20,且保证z小数点后面最多只有一位)。
Output
如果存在满足题目所描述的式子,输出“YES”,否则输出“NO”。
Sample Input
2 2 1 2 0.9 2 1 1.2 6 4 1 2 0.1 2 4 0.8 4 1 12 4 1 15
Sample Output
NO YES
Hint
点的编号为1~n
Source
2017年8月月赛
题目大意:能否在一个有向图中找到一个环,使环上所有边权的乘积小于1。
思路:利用对数的性质,将累加变成累乘。各边取对数作为权值,然后套Bellman-Ford模板判断是否有负圈即可。
#include<cstdio> #include<cmath> #include<cstring> #include<algorithm> using namespace std; const int maxn=505; const int maxm=125005; const double INF=100; double d[maxn]; int n,m; struct edge { int from,to; double cost; }; edge es[maxm]; bool find_negative_loop() { memset(d,0,sizeof(d)); for(int i=1;i<=n;i++) { for(int j=0;j<m;j++) { edge e = es[j]; if(d[e.to]>d[e.from]+e.cost) { d[e.to] = d[e.from] +e.cost; //如果第n次仍然更新了,则存在负圈 if(i==n) return true; } } } return false; } int main() { while(scanf("%d %d",&n,&m)!=EOF) { int i,j,k,a,b; double c; k=0; for(i=0;i<m;i++) { scanf("%d %d %lf",&a,&b,&c); es[k].from = a; es[k].to = b; es[k].cost = log(c); k++; } if(find_negative_loop()) { printf("YES\n"); } else { printf("NO\n"); } } }
时间: 2024-10-13 14:42:31