zoj 3794 spfa
来源:互联网 发布:日本动漫配音软件 编辑:程序博客网 时间:2024/05/16 17:44
给定n个点,m条有向边,邮箱容量c。
起点在1,终点在n,开始邮箱满油。
下面m行表示起点终点和这条边的耗油量(就是长度)
再下面给出一个数字m表示有P个加油站,可以免费加满油。
下面一行P个数字表示加油站的点标。
再下面一个整数Q
下面Q行 u v 表示在u点有销售站,可以卖掉邮箱里的任意数量的油,每以单位v元。
问跑到终点能获得最多多少元。
再华丽的描述外表也掩盖不住水题的性质。
这个题的下手点在 : 卖油只能卖1次,假设在i点处卖油 , 那么我应该要知道2个量,一个是现在油箱里还有多少油,一个是到达终点
还需要多少油。差值就可以卖了。
最大值 1 ,枚举 2 , 满足i处油箱有最多 ; i到n耗油最少。 那么:
正向边 : 求个每个点的最大剩余油量 dist1[i],
反向边 : 求每个点距离终点的最少还需的油量 dist2[i]。
然后枚举一下每个销售点即可,( dist1[i] - dist2[i] ) * wi 。
const int maxn = 1008 ;const int maxm = 100008 ;const int inf = 2000000000 ;struct Graph{ int lis[maxn] ; int id ; struct Edge{ int v ; int w ; int next ; }e[maxm]; void Clear(){ memset(lis , -1 , sizeof(lis)) ; id = 0 ; } void add(int u, int v , int w){ e[id].v = v ; e[id].w = w ; e[id].next = lis[u] ; lis[u] = id++ ; }};Graph g1 , g2 ;int n , m , c ;bool fuel[maxn] ;int sell[maxn][2] ;bool in[maxn] ;int dist1[maxn] , dist2[maxn] ;void spfa1(int s){ queue<int> q ; memset(in , 0 , sizeof(in)) ; in[s] = 1 ; q.push(s) ; fill(dist1+1 , dist1+1+n , -inf) ; dist1[s] = c ; while(! q.empty()){ int u = q.front() ; q.pop() ; in[u] = 0 ; for(int i = g1.lis[u] ; i != -1 ; i = g1.e[i].next){ int v = g1.e[i].v , w = g1.e[i].w ; if(dist1[u] >= w){ //能走完这条路 int t = dist1[u] - w ; if(fuel[v]) t = c ; if(dist1[v] < t){ dist1[v] = t ; if(! in[v]){ in[v] = 1 ; q.push(v) ; } } } } }}void spfa2(int s){ queue<int> q ; memset(in , 0 , sizeof(in)) ; in[s] = 1 ; q.push(s) ; fill(dist2+1 , dist2+1+n , inf) ; dist2[s] = 0 ; while(! q.empty()){ int u = q.front() ; q.pop() ; in[u] = 0 ; for(int i = g2.lis[u] ; i != -1 ; i = g2.e[i].next){ int v = g2.e[i].v , w = g2.e[i].w ; if(dist2[u] + w <= c){ //能走完这条路 int t = dist2[u] + w ; if(fuel[v]) t = 0 ; if(dist2[v] > t){ dist2[v] = t ; if(! in[v]){ in[v] = 1 ; q.push(v) ; } } } } }}int main(){ int i , u , v , w , p , q , s ; while(cin>>n>>m>>c){ g1.Clear() , g2.Clear() ; for(i = 1 ; i <= m ; i++){ scanf("%d%d%d" , &u , &v , &w) ; g1.add(u , v , w) ; g2.add(v , u , w) ; } memset(fuel , 0 , sizeof(fuel)) ; scanf("%d" ,&p) ; for(i = 1 ; i <= p ; i++){ scanf("%d" ,&u) ; fuel[u] = 1 ; } scanf("%d" , &q) ; for(i = 1 ; i <= q ; i++) scanf("%d%d" ,&sell[i][0] , &sell[i][1]) ; spfa1(1) ; if(dist1[n] < 0){ puts("-1") ; continue ; } spfa2(n) ; s = 0 ; for(i = 1 ; i <= q ; i++){ u = sell[i][0] , w = sell[i][1] ; if(dist1[u] >= dist2[u]) s = max(s , (dist1[u] - dist2[u]) * w ) ; } printf("%d\n" , s) ; } return 0 ;}
0 0
- zoj 3794 spfa
- ZOJ 3794 Greedy Driver spfa
- ZOJ 3478 SPFA
- ZOJ 1333 Galactic Import 【SPFA】
- ZOJ 1952 Heavy Cargo【SPFA】
- zoj 3103 Cliff Climbing (SPFA)
- zoj 3088 Easter Holidays (spfa)
- ZOJ 3946Highway Project【spfa】
- ZOJ 3946 Highway Project (spfa)
- ZOJ Problem 3946 (SPFA)
- zoj 1082 Stockbroker Grapevine( 重写 SPFA!)
- ZOJ 1857 && POJ 2607 Fire Station【SPFA】
- POJ 1932 XYZZY (ZOJ 1935)SPFA+floyd
- ZOJ 3080 ChiBi(SPFA,并查集)
- zoj 3088 spfa 最短&最长路径
- zoj 3088 Easter Holidays (spfa )
- zoj 3103 Cliff Climbing(spfa )
- zoj 3847 Collect Chars(ac自动机 + spfa)
- mysql_real_escape_string 什么时候会返回false
- Using Swift with Cocoa and Objective-C--在同个工程中使用Swift和在同个工程中
- 天下会 - Google系列之谷歌搜索引擎高级用法:使用搜索语法精确搜索
- 两个单链表是否相交(考虑有环和无环)
- php实现图片缩放
- zoj 3794 spfa
- void glutInitWindowSize(int width, int height);设置初始窗口的大小
- Android 高手进阶之自定义View,自定义属性(带进度的圆形进度条)
- Java学习之路:不走弯路,就是捷径
- 格式化文本域内容
- FatMouse' Trade
- 网站在线客服系统
- Numpy 入门教程(1)
- 第四讲:实体联系模型