找工作 /*赶集网,58同城弱爆了 如何解决就业失业难题,赚取最多的钱*/ ------->>> 奶牛&FJ!!!
2016-07-17 11:14
309 查看
【问题描述】
奶牛们没钱了,正在找工作。FJ知道后,希望奶牛们四处转转,碰碰运气。而且他还加了一条要求:一头奶牛在一个城市最多只能赚D(0 < D <= 1000)美圆,然后他必须到另一个城市工作。当然,他可以在别处工作一阵后又回来再多赚D美圆。而且这样往往返返的次数没有限制。
城市间P(1<=P<=150)条单向道路连接,共有N(2<=N<=300)座城市(编号为1..N)。贝西当前在城市S。道路i从城市Ai到城市Bi,在道路上行走不用花费任何费用。
为了帮助贝西,FJ让他使用他的私人飞机,飞机有F(1<=F<=350)条航线,第j条航线是从城市Aj到城市Bj,费用是Tj(1<=Tj<=50000)美圆,如果贝西手中没有现钱,可以用以后赚的钱来付机票钱,贝西可以选择任何时候,任何城市退休。
如果在工作时间上不作限制,贝西总共可以赚多少钱呢?如果赚的钱不会出现限制,就输出INF。
【输入格式】
第1行:5个空格分开的整数D,P,N,F,S
第2到第P+1行:第i+1行包含2个空格分开的整数,表示从Ai到Bi的单向道路。
第P+2到P+F+1行:第P+j包括3个空格分开的整数,表示一条从Aj到Bj的单向航线,费用为Tj
【输出格式】
在上述规则下得最多可赚得钱数。
【输入样例】
【样例1】
100 3 5 2 1
1 5
2 3
1 4
5 2 150
2 5 120
【样例2】
100 3 5 2 1
1 5
2 3
1 4
5 2 70
2 5 120
【输出样例】
【样例1】
250
【样例2】
INF
【数据范围】
N<=300
简单的找权值和最大的路径,有正环则输出INF。生成好了边权后直接用spfa算法算出s为起点的dist。
另一种常规做法(但是要慢些)
奶牛们没钱了,正在找工作。FJ知道后,希望奶牛们四处转转,碰碰运气。而且他还加了一条要求:一头奶牛在一个城市最多只能赚D(0 < D <= 1000)美圆,然后他必须到另一个城市工作。当然,他可以在别处工作一阵后又回来再多赚D美圆。而且这样往往返返的次数没有限制。
城市间P(1<=P<=150)条单向道路连接,共有N(2<=N<=300)座城市(编号为1..N)。贝西当前在城市S。道路i从城市Ai到城市Bi,在道路上行走不用花费任何费用。
为了帮助贝西,FJ让他使用他的私人飞机,飞机有F(1<=F<=350)条航线,第j条航线是从城市Aj到城市Bj,费用是Tj(1<=Tj<=50000)美圆,如果贝西手中没有现钱,可以用以后赚的钱来付机票钱,贝西可以选择任何时候,任何城市退休。
如果在工作时间上不作限制,贝西总共可以赚多少钱呢?如果赚的钱不会出现限制,就输出INF。
【输入格式】
第1行:5个空格分开的整数D,P,N,F,S
第2到第P+1行:第i+1行包含2个空格分开的整数,表示从Ai到Bi的单向道路。
第P+2到P+F+1行:第P+j包括3个空格分开的整数,表示一条从Aj到Bj的单向航线,费用为Tj
【输出格式】
在上述规则下得最多可赚得钱数。
【输入样例】
【样例1】
100 3 5 2 1
1 5
2 3
1 4
5 2 150
2 5 120
【样例2】
100 3 5 2 1
1 5
2 3
1 4
5 2 70
2 5 120
【输出样例】
【样例1】
250
【样例2】
INF
【数据范围】
N<=300
简单的找权值和最大的路径,有正环则输出INF。生成好了边权后直接用spfa算法算出s为起点的dist。
另一种常规做法(但是要慢些)
#include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> #include<vector> #define maxn 1006 #define oo 1000000000 using namespace std; int n,m,D,P,s,x,y,z,front,rear; int w[maxn][maxn]={0},dist[maxn],q[maxn*maxn],vis[maxn]={0}; vector<int>g[maxn]; bool inq[maxn]; void in() { scanf("%d%d%d%d%d",&D,&P,&n,&m,&s); for(int i=1;i<=P;i++) { scanf("%d%d",&x,&y); g[x].push_back(y); w[x][y]=D; //走过这一条边赚D } for(int i=1;i<=m;i++) { scanf("%d%d%d",&x,&y,&z); g[x].push_back(y); w[x][y]=D-z; //赚D,花z,则边权为D-z; } } bool spfa() { for(int i=1;i<=n;i++) dist[i]=-oo; front=rear=1; q[rear++]=s; inq[s]=1; dist[s]=D; vis[s]++; while(front!=rear) { int i=q[front++]; inq[i]=0; for(int k=0;k<g[i].size();k++) { int j=g[i][k]; int l=w[i][j]; if(dist[i]+l>dist[j]) { dist[j]=dist[i]+l; if(inq[j]) continue; q[rear++]=j; inq[j]=1; vis[j]++; if(vis[j]>n) return true;//返回有正环 } } } return false; } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); in(); bool ok=spfa(); if(ok) { printf("INF"); return 0; } int ans=0; for(int i=1;i<=n;i++) ans=max(ans,dist[i]);//查找最大值 printf("%d",ans); return 0; }
相关文章推荐