ZOJ 1508 Intervals (差分约束系统+spfa)

通化邀请赛结束了。。。四题拿铜,还是太弱了。。。回来后连续两周的省赛和东北赛。。。最近准备搞搞图论和树形dp,最短路的差分约束系统应用一直没做,今天看了看国家队冯威的论文《树与图的完美结合--浅析差分约束系统》,感觉讲的挺详细的。。照着论文中的思路切了这道模板题。。。刚开始不知道如何输出结果,又再看了一遍论文,由于 s[i]数组保存0~i中数组元素集合的大小,所以从Max做spfa,答案便是-d[Min-1]。。。不懂就好好看论文把!

#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<cstdio>
#include<cstring>
using namespace std;

const int maxn = 55555;
const int INF = 1e9;
int n, m, s, a, b, c;
int d[maxn], inq[maxn];
struct Edge
{
    int from, to, dist;
    Edge(){};
    Edge(int u, int v, int d){from=u;to=v;dist=d;};
};
vector<Edge> edges;
vector<int> G[maxn];

void init()
{
    for(int i=0; i<maxn; i++)   G[i].clear();
    edges.clear();
}

void add(int from, int to, int dist)
{
    Edge e = Edge(from, to, dist);
    edges.push_back(e);
    int tmp = edges.size();
    G[from].push_back(tmp-1);
}

int spfa(int s, int t)
{
    queue<int> q;   q.push(s);
    memset(inq, 0, sizeof(inq));
    for(int i=0; i<=maxn; i++)  d[i] = INF;
    d[s] = 0;  inq[s] = 1;
    while(!q.empty())
    {
        int u = q.front();  q.pop();
        inq[u] = 0;
        for(int i=0; i<G[u].size(); i++)
        {
            Edge& e = edges[G[u][i]];
            if(d[e.to] > d[u] + e.dist)
            {
                d[e.to] = d[u] + e.dist;
                if(!inq[e.to])
                {
                    q.push(e.to);
                    inq[e.to] = 1;
                }
            }
        }
    }
    return -d[t-1];
}

int main()
{
    while(~scanf("%d", &m))
    {
        init();
        int Max = -1, Min = INF;
        while(m--)
        {
            scanf("%d%d%d", &a, &b, &c);
            a++; b++;
            add(b, a-1, -c);
            Max = max(max(Max, a), b);
            Min = min(min(Min, a), b);
        }
        for(int i=Min; i<=Max; i++)
        {
            add(i, i-1, 0);
            add(i-1, i, 1);
        }
        printf("%d\n", spfa(Max, Min));
    }
}


你可能感兴趣的:(ZOJ,SPFA)