LightOj 1221 - Travel Company(spfa判负环)

1221 - Travel Company

PDF (English) Statistics Forum
Time Limit: 2 second(s) Memory Limit: 32 MB

A travel company is planning to launch their bus service in a new route. So they conducted a survey and made a list of all possible roads connecting different cities. Each of the roads has a certain amount of income based on current fare. But at the same
time, each road has some expenses too (this includes fuel and maintenance cost, staff payments, taxes and tribute to labor union which is recently approved by the Government). The travel company is looking for a cyclic route. That is, the bus will start from
any city, then visit one or more cities each exactly once and return to the starting city. The company is also concerned with the profit on the route. In fact the directors of the company have a strict requirement of a profit ratio strictly greater than P.
Otherwise they will not launch the service. A profit ratio for a route is the ratio between the total incomes to the total expenses for that route.

One of your friends works in that company and he asks for a little help from you. All you have to do is to determine if there exists such route, so that the company has a profit ratio of P.

Input

Input starts with an integer T (≤ 100), denoting the number of test cases.

Each case starts with a blank line and three integers N, R, P (2 ≤ N ≤ 100, 0 ≤ R ≤ 9900, 1 ≤ P ≤ 100)NR and Prepresents number of cities, number of road links and the expected profit
ratio respectively. Then R lines follow. Each line contains four integers Ai, Bi, Ii, Ei (0 ≤ Ai, Bi < N, 0 ≤ Ii ≤ 5000, 1 ≤ Ei ≤ 5000)(Ai,
Bi)
 represents directed road link from city Ai to BiIi and Ei are the incomes and expenses of the road link respectively.
You may assume that (Ai, Bi) ≠ (Aj, Bj), if i ≠ j and Ai ≠ Bi for any i.

Output

For each case, print the case number and "YES" if there is a cyclic route for which the profit ratio is greater than P or "NO", if there is no such route.

Sample Input

Output for Sample Input


3

5 8 3

0 1 17 8

1 0 10 5

1 2 11 5

1 4 5 3

2 3 13 7

3 1 9 4

4 3 11 1

3 0 11 6

5 8 3

0 1 17 8

1 0 10 5

1 2 11 5

1 4 5 3

2 3 13 7

3 1 9 4

4 3 11 2

3 0 11 6

5 8 2

0 1 17 8

1 0 10 5

1 2 11 5

1 4 5 3

2 3 13 7

3 1 9 4

4 3 11 5

3 0 11 6


Case 1: YES

Case 2: NO

Case 3: YES

首先申明这道题是看的scf的题意,一开始没读懂题,结果直接抄袭人家题意,敲了个spfa,忘了初始化vector调了一下午没弄好。。晚上认真读了一遍英语,仔细一想这题真的是很巧妙,题意:旅游公司推出了一种新的旅游路线,这里有n个城市,编号为0--n-1,有m条路线,每行输入u v in out 4个变量,u v 代表编号为u和v的两个城市相连,in代表旅游公司在这条路线上的收入,out代表支出,最开始一行给出一个利润率p(收入/支出),公司要求找到一条循环路线(即一个环),使得总利率大于p;

我们可以根据题意写出这么一条原始的公式:(in[0]+in[1]+....in[k])/(out[0]+out[1]+...out[k])>p 即 p*(out[0]+out[1]+...out[k])<(in[0]+in[1]+....in[k]),总结一下就是对于这个环中的任意一条边,都要求
p*out[k]-in[k]<0 即在图中存在负环,证明完毕。

用spfa判负环要注意要以每个点为起点判一遍(如果存在负环可以直接退出),判负环的原理是只要有一个点入队次数大于n(点的总个数),则存在负环。因为最短路最多对边松弛n-1次就可以求出来,如果一个点入队次数大于n,说明一定存在负环,即不存在最短路。

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cctype>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <list>
using namespace std;
const  int maxn=50100;
const int INF=0x3f3f3f3f;
int n,m,dis[maxn],vis[maxn],intime[maxn];
vector < pair<int,int> > eg[maxn];
int spfa(int src)
{
	queue <int> Q;
	memset(dis,INF,sizeof(dis));
	memset(vis,0,sizeof(vis));
	memset(intime,0,sizeof(intime));
	dis[src]=0;
	Q.push(src);
	while(!Q.empty())
	{
      int u=Q.front();Q.pop();
      vis[u]=0;intime[u]++;
      if(intime[u]>n)
		return 1;
	  int len=eg[u].size();
	  for(int i=0;i<len;i++)
	  {
	  	int v=eg[u][i].first;
	  	int w=eg[u][i].second;
	  	if(dis[v]>dis[u]+w)
		{
			dis[v]=dis[u]+w;
			if(!vis[v])
			{
				vis[v]=1;
				Q.push(v);
			}
		}
	  }
	}
	return 0;
}
int main()
{
    int T,p,cas=1;
    scanf("%d",&T);
    while(T--){
		scanf("%d%d%d",&n,&m,&p);
		for(int i=0;i<=n;i++)
			eg[i].clear();
		while(m--)
		{
			int u,v,in,out;
			scanf("%d%d%d%d",&u,&v,&in,&out);
			int tem=out*p-in;
			eg[u].push_back(make_pair(v,tem));
		}
		printf("Case %d: ",cas++);
		int flag=1;
		for(int i=0;i<n;i++)
		{
			if(spfa(i))
			{
				flag=0;
				printf("YES\n");
				break;
			}
		}
		if(flag)
			printf("NO\n");
    }
	return 0;
}

时间: 2024-10-08 20:50:24

LightOj 1221 - Travel Company(spfa判负环)的相关文章

Poj3259--Wormholes(Spfa 判负环)

Wormholes Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 36836   Accepted: 13495 Description While exploring his many farms, Farmer John has discovered a number of amazing wormholes. A wormhole is very peculiar because it is a one-way p

poj3259 Wormholes --- spfa判负环

又写了个bellman模板一直RE求解啊... #include <iostream> #include <cstring> #include <string> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <queue> #include <map> #define inf 0x

uva11090 Going in Cycle!! --- 二分+spfa判负环

给一个带权有向图,求其中是否存在环,若存在,输出环上边权的平均值最小的那个的平均值. 点的范围就50,感觉可以很暴力..但显然超时了 感觉方法好巧妙,二分平均值,将所有边权减去二分的那个值,然后spfa判断是否有负环 若有负环,则图中存在的所有环的边权平均值一定比枚举值大 反之则小,要是无论枚举值多大都没有负环,说明图中没有环. #include <iostream> #include <cstring> #include <string> #include <c

POJ-1860 Currency Exchange 【spfa判负环】

Description Several currency exchange points are working in our city. Let us suppose that each point specializes in two particular currencies and performs exchange operations only with these currencies. There can be several points specializing in the

LightOJ 1074 Extended Traffic SPFA 消负环

分析:一看就是求最短路,然后用dij,果断错了一发,发现是3次方,有可能会出现负环 然后用spfa判负环,然后标记负环所有可达的点,被标记的点答案都是“?” #include<cstdio> #include<cstring> #include<queue> #include<cstdlib> #include<algorithm> #include<vector> #include<cmath> using namesp

POJ 3259 Wormholes(SPFA判负环)

题目链接:http://poj.org/problem?id=3259 题目大意是给你n个点,m条双向边,w条负权单向边.问你是否有负环(虫洞). 这个就是spfa判负环的模版题,中间的cnt数组就是记录这个点松弛进队的次数,次数超过点的个数的话,就说明存在负环使其不断松弛. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 using na

bzoj1690:[Usaco2007 Dec]奶牛的旅行(分数规划+spfa判负环)

前段时间准备省选没更,后段(?)时间省选考砸没心情更,最近终于开始恢复刷题了... 题目大意:有n个点m条有向边的图,边上有花费,点上有收益,点可以多次经过,但是收益不叠加,边也可以多次经过,但是费用叠加.求一个环使得收益和/花费和最大,输出这个比值. 显然这就是经典的分数规划题啊,就是最优比率环,那么就二分答案,将所有边(u,v)的边权改为[v的点权-(u,v)原边权*mid],这可以算是最优比率环的公式了吧,然后判一下是否有正环,有的话就说明答案可行.判正环有够别扭的,那就全部改成相反数然后

P2136 拉近距离(spfa判负环)

洛谷—— P2136 拉近距离 题目背景 我是源点,你是终点.我们之间有负权环. ——小明 题目描述 在小明和小红的生活中,有N个关键的节点.有M个事件,记为一个三元组(Si,Ti,Wi),表示从节点Si有一个事件可以转移到Ti,事件的效果就是使他们之间的距离减少Wi. 这些节点构成了一个网络,其中节点1和N是特殊的,节点1代表小明,节点N代表小红,其他代表进展的阶段.所有事件可以自由选择是否进行,但每次只能进行当前节点邻接的.请你帮他们写一个程序,计算出他们之间可能的最短距离. 输入输出格式

BZOJ 3436 小K的农场 查分约束系统 SPFA判负环

题目大意:农场中有一些土地,上面会长一些作物,现在给出一些约束条件,问有没有这种可能. 思路:裸的查分约束系统判负环.记住要跑最长路. CODE: #include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 100010 using namespace std; int points,asks;