• LightOj 1221


    1221 - Travel Company

    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
    ");
    				break;
    			}
    		}
    		if(flag)
    			printf("NO
    ");
        }
    	return 0;
    }
    


  • 相关阅读:
    C语言清空输入缓冲区的N种方法对比(转)
    UNIX网络编程——socket的keep-alive(转)
    UNIX网络编程——套接字选项(心跳检测、绑定地址复用)(转)
    UNIX网络编程——客户/服务器心搏函数 (转)
    TCP心跳 | TCP keepAlive(转)
    linux下使用adb查看android手机的logcat
    linux 常用查看设备命令(转)
    Spring AOP 详解
    HDU 2222 AC自动机 裸题
    大声说出我爱你—英语发音学习总结
  • 原文地址:https://www.cnblogs.com/brucemengbm/p/6744297.html
Copyright © 2020-2023  润新知