zoj 2583 || poj 2679 Adventurous Driving

恶心题过一道就少一道~~~撒花花~~~不让用表情,我随便搜个吧~~chrome的频率好快。。

 

这题啊,理解题意是件很困难的事情~

 

先说题意吧,给你起点,终点,边,以及边的长度 和从这边到那边的花费,而且必须走这么一条路。。。即当前点,花费最少的的路,而且最终长度最短的路。如果从s到t上存在负环,输出UNXXXX,如果没有这种路,输出VOID。

 

关于VOID这个路哈,样例我始终理解不了,就在昨天,突然理解啦!!!哈哈!把不是最优的边删掉,就可能到达不了了哦。。。就是VOID。

 

反正就是先删边啦。。。删边纠结了许久 = = 。。。然后找负环又纠结了。我本来用的SPFA,然后判断出来负环后,用DIJKSTRA,发现有问题。有很大问题T T 。。。后来求长度也有问题,各种问题啊!!!后来发现,如果直接求长度的最短路,可能花费不是最小的,需要在花费最小的前提下求得最短的路T T。。。然后改了改。。。各种数据,XH同学提供的数据很打击人啊。。。T T各种不匹配。。

 

后来发现,还是判断点是否在负环里是个大问题,最终用别人的思路,bellmanford判断前后路程是否改变,但是如果需要松弛多次才能判断出来的话,用bellman还是判断不出来,所以就需要把在负环上的弄得很小,使他足够使它连接的点得到松弛~

 

改了一天了,A掉了,把党姐刷下去了。。。Bellman-ford终于有用武之地了^ ^

 

#include <queue> #include <stack> #include <math.h> #include <stdio.h> #include <stdlib.h> #include <iostream> #include <limits.h> #include <string.h> #include <algorithm> #define MAX 1110 using namespace std; typedef struct NODE{ int v,cost,len; NODE *next; }NODE; NODE *p[MAX],node[10010]; typedef struct BNODE{ int u,v,cost; }BNODE; BNODE edge[10010]; int cou; void init() { cou = 0; memset(node,'/0',sizeof(node)); memset(p,'/0',sizeof(p)); } void Add(int u,int v,int fuv,int len) { node[cou].v = v; node[cou].cost = fuv; node[cou].len = len; node[cou].next = p[u]; p[u] = &node[cou++]; } queue<int> q; int cost[MAX]; int dis[MAX]; int SPFAFU(int s,int t,int n) { bool inq[MAX]; int cnt[MAX]; memset(inq,false,sizeof(inq)); memset(cnt,0,sizeof(cnt)); fill(cost,cost+n,INT_MAX); fill(dis,dis+n,INT_MAX); dis[s] = 0; inq[s] = true; cost[s] = 0; cnt[s] = 1; while( !q.empty() ) q.pop(); q.push(s); int flag = 1; while( !q.empty() ) { int now = q.front(); q.pop(); inq[now] = false; NODE *head = p[now]; while( head != NULL ) { int len = head->cost; int to = head->v; if( cost[to] > cost[now] + len || cost[to] == cost[now] + len && dis[to] > dis[now] + head->len ) { cost[to] = cost[now] + len; dis[to] = dis[now] + head->len; if( !inq[to] ) { inq[to] = true; if( ++cnt[to] > n ) { flag = 0; break; } q.push(to); } } head = head->next; } if( !flag ) break; } if( cost[t] == INT_MAX ) return 0; /********************************Bellmanford*********************************/ int bcou = 0; for(int i=0; i<n; i++) { NODE *head = p[i]; while( head != NULL ) { edge[bcou].u = i; edge[bcou].v = head->v; edge[bcou++].cost = head->cost; head = head->next; } } int tmp = cost[t]; for(int i=0; i<n; i++) for(int k=0; k<bcou; k++) if( cost[edge[k].u] != INT_MAX && cost[edge[k].v] > cost[edge[k].u] + edge[k].cost ) cost[edge[k].v] = -1000000; if( tmp > cost[t] ) return -1; return 1; } void Delete(int n) { for(int i=0; i<n; i++) { NODE *head = p[i]; int min = INT_MAX; while( head != NULL ) { if( head->cost < min ) min = head->cost; head = head->next; } head = p[i]; NODE *pre = p[i]; while( head != NULL ) { if( head->cost != min ) { if( head == p[i] ) { p[i] = head->next; pre = head = p[i]; } else { pre->next = head->next; head = pre->next; } } else { pre = head; head = head->next; } } } } int main() { int n,m,s,t,u,v,fuv,fvu,len; char str[100]; while( ~scanf("%d%d%d%d",&n,&m,&s,&t) ) { init(); while( m-- ) { scanf("%s",str); sscanf(str,"(%d,%d,%d[%d]%d)",&u,&v,&fuv,&len,&fvu); Add(u,v,fuv,len); Add(v,u,fvu,len); } Delete(n); int ans = SPFAFU(s,t,n); if( ans == -1 ) printf("UNBOUND/n"); else if( ans == 0 ) printf("VOID/n"); else printf("%d %d/n",cost[t],dis[t]); } return 0; }  

你可能感兴趣的:(zoj 2583 || poj 2679 Adventurous Driving)