HDU 4109 Instrction Arrangement 拓扑排序+dp 或者 差分约束
http://acm.hdu.edu.cn/showproblem.php?pid=4109
给定N个指令,其中有部分指令存在先后时间上的顺序,给定m个,x, y, z 即y必须在x执行完z秒后才执行,求 最少的时间。
首先根据拓扑排序找出入度为0点,处理,而对于有限制的一些点来说,dp[i] = max(dp[i],dp[j] + w) j 是i的临接点,w是i与j 的时间差。边表不是很熟,同时也练习了一下边表。。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <cstdio> #include <cstring> #include <iostream> #include <queue> #define maxe 10007 #define maxv 1007 using namespace std; struct node { int v; int w; int next; }e[maxe]; int p[maxe],inde[maxv]; int n,m,len; int dp[maxv]; void init() { len = 0; for (int i = 0; i < maxe; ++i) p[i] = -1; for (int i = 0; i < maxv; ++i) { inde[i] = 0; dp[i] = 0; } } void insert(int x,int y,int z) { e[len].v = y; e[len].w = z; e[len].next = p[x]; p[x] = len++; } int main() { int i; int x,y,z; while (~scanf("%d%d",&n,&m)) { init(); for (i = 0; i < m; ++i) { scanf("%d%d%d",&x,&y,&z); insert(x,y,z); inde[y]++; } queue<int>q; for (i = 0; i < n; ++i) { if (inde[i] == 0) { inde[i] = -1; q.push(i); dp[i] = 1; } } while (!q.empty()) { int u = q.front(); q.pop(); for (i = p[u]; i != -1; i = e[i].next) { int v = e[i].v; dp[v] = max(dp[v],dp[u] + e[i].w); inde[v]--; if (inde[v] == 0) { inde[v] = -1; q.push(v); } } } int ans = dp[0]; for (i = 1; i < n; ++i) { ans = max(ans,dp[i]); } printf("%d\n",ans); } return 0; }
差分约束。。由于要满足所有的约束条件,所以建立一个一个源点与汇点,
然后就是差分约束图模型的建立了。建立后利用bellman_ford或者spfa求最短路。即为所求解
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <cmath> #define N 1007 #define M 10002 using namespace std; struct node { int u,v; int w; }p[M]; int dis[N]; int n,m,len; void bellman() { int i,j; for (i = 1; i <= n + 1; ++i) { for (j = 0; j < len; ++j) { if (dis[p[j].v] > dis[p[j].u] + p[j].w) dis[p[j].v] = dis[p[j].u] + p[j].w; } } } int main() { //freopen("data.in","r",stdin); int i,x,y,z; while (~scanf("%d%d",&n,&m)) { for (i = 0; i <= n + 1; ++i) dis[i] = 0; for (i = 0; i < m; ++i) { scanf("%d%d%d",&x,&y,&z); p[i].u = x + 1; p[i].v = y + 1; p[i].w = -z; } len = i; for (i = 1; i <= n; ++i) { p[len].u = 0; p[len].v = i; p[len].w = 0; len++; p[len].u = i; p[len].v = n + 1; p[len].w = 0; len++; } bellman(); printf("%d\n",1 - dis[n + 1]); } return 0; }