通化邀请赛结束了。。。四题拿铜,还是太弱了。。。回来后连续两周的省赛和东北赛。。。最近准备搞搞图论和树形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));
}
}