Poj 2983 (差分约束系统)

     还是那句话:差分约束条件题目的难点是“怎么找到问题的约束条件”。

这题输入的边有两种格式:

      1. 边长确定,即xi - xj = b; 可以转化成 xi - xj <= b 和 xi - xj >=b (即 xj - xi <= -b).

      2. 边长不定,xi - xj >= 1; 可以转化成 xj - xi <= -1;

 

下面用SPFA算法实现:

#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#define MAXV 1005  
#define MAXE 201005  
#define INF  100000000  
struct  
{  
    int  e, v;  
} edge[MAXE];  
int n, neg;  
int dis[MAXV], cnt[MAXV];  
int node[MAXV], next[MAXE];  
int Q[MAXV], vst[MAXV];  
void add(int s, int e, int v)  
{  
    edge[neg].e = e;  
    edge[neg].v = v;  
    next[neg] = node[s];  
    node[s] = neg++;  
}  
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, t, p, top;  
    memset(cnt, 0, sizeof(cnt));  
    memset(vst, 0, sizeof(vst));  
    for (i=0; i<=n; i++)  
        dis[i] = INF;  
    dis[s0] = 0;  
    Q[0] = s0;  
    top = 1;  
    vst[s0] = 1;  
    cnt[s0]++;  
    while (top)  
    {  
        t = Q[--top];  
        vst[t] = 0;  
        p = node[t];  
        while (p != -1)  
        {  
            if (relax(t, edge[p].e, edge[p].v) && !vst[edge[p].e])  
            {  
                Q[top++] = edge[p].e;  
                vst[edge[p].e] = 1;  
                cnt[edge[p].e]++;  
                if (cnt[edge[p].e] > n+1)  
                    return 0;  
            }  
            p = next[p];  
        }  
    }  
    return 1;  
}  
int main()  
{  
    int  m, a, b, c, i;  
    char f;  
    while (scanf("%d %d", &n, &m) != EOF)  
    {  
        neg = 0;  
        memset(node, -1, sizeof(node));  
        while (m--)  
        {  
            scanf("%*c %c %d %d", &f, &a, &b);  
            if (f == 'P')  
            {  
                scanf("%d", &c);  
                add(a, b, c);  
                add(b, a, -c);  
            }  
            else  
                add(b, a, -1);  
        }  
        //添加一个结点0作为源点  
        for (i=1; i<=n; i++)  
            add(0, i, 1);  
        if (SPFA(0))  
            printf("Reliable/n");  
        else  
            printf("Unreliable/n");  
    }  
}


你可能感兴趣的:(c,算法,struct,2010)