zoukankan      html  css  js  c++  java
  • 洛谷P1938 找工就业

    传送门啦

    这个题本质就是跑一边最长路,重点就是在怎么建图上。

    我们可以把点权放到边权上面,即将每一个边的终点点权当做这个边的边权,这个题里就是将工钱 $ d $ 当做边权。

    如果这一条边需要坐飞机才能到达,我们就可以将 $ d-w $ 当做边权进行建图,这个时候你发现了什么??

    你会发现 $ d-w $ 可能是个负值,所以我们跑最长路的时候就不能用 $ dijk $了。

    最后我们就考虑怎么判断无限挣钱的情况了,那个情况下就是出现了环,可以不断走。所以我们开一个数组,记录一下每条最长路上点的个数,只要大于 $ c $ ,就是说明我们走了一个环,就打一个标记,判断一下输出 $ -1 $

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    using namespace std;
    const int maxn = 2000;
    
    inline int read(){
    	char ch = getchar();
    	int f = 1 , x = 0;
    	while(ch > '9' || ch < '0'){if(ch == '-')f = -1;ch = getchar();}
    	while(ch >= '0' && ch <= '9'){x = (x << 1) + (x << 3) + ch - '0';ch = getchar();}
    	return x * f;
    }
    
    int d,p,c,f,s,u,v,w;
    struct Edge{
    	int to,from,val,next;
    }edge[maxn << 1];
    int head[maxn],tot;
    int dis[maxn],ans,go[maxn];
    bool flag,vis[maxn];
    
    void add(int u,int v,int w){
    	edge[++tot].from = u;
    	edge[tot].to = v;
    	edge[tot].val = w;
    	edge[tot].next = head[u];
    	head[u] = tot;
    }
    
    struct node{
    	int u,dist;
    	bool operator < (const node &x) const{
    		return dist > x.dist;
    	}
    }; 
    	
    void spfa(int s){
    	queue<int> q;
    	q.push(s);
    	dis[s] = d; vis[s] = true;
    	while(!q.empty()){
    		int cur = q.front();
    		q.pop(); vis[cur] = false;
    		for(int i=head[cur];i;i=edge[i].next){
    			int v = edge[i].to;
    			if(dis[v] < dis[cur] + edge[i].val){
    				dis[v] = dis[cur] + edge[i].val;
    				go[v] = go[u] + 1;
    				if(go[v] > c){
    					flag = true;
    					return;
    				}
    				if(!vis[v]){
    					q.push(v);
    					vis[v] = true;
    				}
    			}
    		}
    	}
    }
    	
    int main(){
    	d = read(); p = read(); c = read(); f = read(); s = read();
    	for(int i=1;i<=p;i++){
    		u = read(); v = read();
    		add(u , v , d);
    	}
    	for(int i=1;i<=f;i++){
    		u = read(); v = read(); w = read();
    		add(u , v , d-w);
    }
    	spfa(s);
    	if(flag == 1){printf("-1
    ");return 0;}
    	for(int i=1;i<=c;i++)
    		ans = max(ans , dis[i]);
    	printf("%d
    ",ans);
    	return 0;
    }
    顺风不浪,逆风不怂。
  • 相关阅读:
    HTMLParser使用
    SpringMVC学习系列(6) 之 数据验证
    SpringMVC学习系列 之 表单标签
    开源OSS.Social微信项目解析
    源码分析——核心机制
    Struts2 源码分析——过滤器(Filter)
    调结者(Dispatcher)之执行action
    配置管理之PackageProvider接口
    源码分析——Action代理类的工作
    DefaultActionInvocation类的执行action
  • 原文地址:https://www.cnblogs.com/Stephen-F/p/9875613.html
Copyright © 2011-2022 走看看