poj 2983 Is the Information Reliable?(差分约束)
啊!啊!啊!快要哭了,调了一下午加一晚上,怎么也找不出错误,感觉自己理解的也没错,怎么就是不对呢,在我要崩溃的时候终于AC了,原因竟然是因为判断条件没用函数,真的崩溃了!!题意:给出N个点,有些点的位置是清晰的, 有些点的位置不清楚,只知道点A在点B的北面,清晰的点有两点间的距离, 不清晰的点只知道两点的距离不小于1。
思路:这题时用差分约束做的,刚开始接触差分约束,知道要先找到不等式,但这题里有些是等式,要先转化成不等式,即 c<= dis[i] + dis[j] <= c ;不清晰的点有不等式d[i] + d[j] >= 1;
然后直接用差分约束模板就解决了!我是用的SPFA~
AC代码:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <iostream> #include <algorithm> #include <math.h> #define N 1005 #define M 201010 #define INF 100000000 using namespace std ; struct node { int e ; int v ; }p[M] ; int next[M] , node[N] ; int mark[N] , num[N] ; int q[N] , top ; int dis[N] , cnt ; int n , m ; void add ( int s , int e , int v ) { p[cnt].e = e ; p[cnt].v = v ; next[cnt] = node[s] ; node[s] = cnt++ ; } int Relax ( int s , int e , int v ) { if ( dis[s] + v < dis[e] ) { dis[e] = dis[s] + v ; return 1 ; } return 0 ; } int spfa ( int s0 ) { int i , k , t ; memset( mark , 0 , sizeof ( mark )); memset( num , 0 , sizeof ( num )); for ( i = 0 ; i <= n ; i++ ) dis[i] = INF ; dis[s0] = 0 ; top = 0 ; q[top++] = s0 ; mark[s0] = 1 ; num[s0]++ ; while ( top ) { t = q[--top] ; mark[t] = 0 ; k = node[t] ; while ( k != -1 ) { if ( Relax ( t , p[k].e , p[k].v ) && !mark[p[k].e] ) //if ( dis[t] + p[k].v < dis[p[k].e] && !mark[p[k].e] )就WA了,调用了Relax就对了。 { q[top++] = p[k].e ; mark[p[k].e] = 1 ; num[p[k].e]++ ; //dis[aa] = dis[t] + bb ; if ( num[p[k].e] > n + 1) return 0 ; } k = next[k] ; } } return 1 ; } int main() { int i , j , x , y , v ; char c ; while ( scanf ( "%d%d" , &n , &m ) != EOF ) { getchar(); memset( node , -1 , sizeof ( node )); cnt = 0 ; for ( i = 0 ; i < m ; i++ ) { scanf ( "%c%d%d" , &c , &x , &y ); if ( c == 'P' ) { scanf ( "%d" , &v ); add ( x , y , v); add ( y , x , -v ); } else add ( y , x , -1 ); getchar(); } for ( i = 1 ; i <= n ; i++ ) add ( 0 , i , 1 ); if ( spfa( 0 )) printf ( "Reliable\n" ); else printf ( "Unreliable\n" ); } return 0 ; }