首页 > 代码库 > POJ 3159[差分约束]

POJ 3159[差分约束]

题目链接:【http://poj.org/problem?id=3159】

题意:有N个小朋友,编号为1-N,每个小朋友将分的一些糖果,给出一些关系A、B、C .表示B最多比A多C个,然后问你盆友1和盆友N的糖果数最大差多少。保证有解。

题解:差分约束求最短距离:DIJ+对优化||SPAF+栈优化

 

#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int INF = 1e9 + 17;
const int maxn = 30050;
struct Edge
{
    int id, next, len;
    Edge(int id = 0, int next = 0, int len = 0): id(id), next(next), len(len) {}
} E[maxn << 3];
int head[maxn], tot;
void init()
{
    memset(head, -1, sizeof(head));
    tot  = 0;
}
void adde(int u, int v, int dis)
{
    E[tot] = Edge(v, head[u], dis);
    head[u] = tot++;
}
int N, M;
int u, v, c;
int dis[maxn], vis[maxn];
int DIJ(int st, int ed)
{
    for(int i = 1; i <= N; i++)
        dis[i] = INF, vis[i] = 0;
    dis[st] = 0;
    priority_queue<int>que;
    que.push(st);
    while(!que.empty())
    {
        int u = que.top();
        que.pop();
        if(vis[u]) continue;
        for(int k = head[u]; ~k; k = E[k].next)
        {
            int v = E[k].id;
            if(dis[v] > dis[u] + E[k].len)
            {
                dis[v] = dis[u] + E[k].len;
                que.push(v);
            }
        }
    }
    return dis[ed];
}
int main ()
{
    scanf("%d%d", &N, &M);
    {
        init();
        for(int i = 1; i <= M; i++)
        {
            scanf("%d%d%d", &u, &v, &c);
            adde(u, v, c);
        }
        int dis = DIJ(1, N);
        printf("%d\n", dis);
    }
    return 0;
}

 

SPFA+栈优化

#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int INF = 1e9 + 17;
const int maxn = 30050;
struct Edge
{
    int id, next, len;
    Edge(int id = 0, int next = 0, int len = 0): id(id), next(next), len(len) {}
} E[maxn << 3];
int head[maxn], tot;
void init()
{
    memset(head, -1, sizeof(head));
    tot  = 0;
}
void adde(int u, int v, int dis)
{
    E[tot] = Edge(v, head[u], dis);
    head[u] = tot++;
}
int N, M;
int u, v, c;
int dis[maxn], in[maxn];
int que[maxn];
int SPFA(int st, int ed)
{
    for(int i = 1; i <= N; i++)
        dis[i] = INF, in[i] = 0;
    dis[st] = 0;
    int top = 0;
    que[top++] = st;
    in[st] = 1;
    while(top)
    {
        int u = que[--top];
        in[u] = 0;
        for(int k = head[u]; ~k; k = E[k].next)
        {
            int v = E[k].id;
            if(dis[v] > dis[u] + E[k].len)
            {
                dis[v] = dis[u] + E[k].len;
                if(in[v]) continue;
                in[v] = 1;
                que[top++] = v;
            }
        }
    }
    return dis[ed];
}
int main ()
{
    scanf("%d%d", &N, &M);
    {
        init();
        for(int i = 1; i <= M; i++)
        {
            scanf("%d%d%d", &u, &v, &c);
            adde(u, v, c);
        }
        int dis = SPFA(1, N);
        printf("%d\n", dis);
    }
    return 0;
}

 

POJ 3159[差分约束]