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