BZOJ 3890 Usaco2015 Jan Meeting Time 拓扑图DP

题目大意

题上的中文题意太不明确了。。。 给出一个拓扑图,每条有向边有两个权值,有两个人从1出发到n,,分别走这两种权值。问有没有权值使得这两个人都能走过这些权值到达n。

思路

看懂了题之后就水了。维护两个数组表示从1号节点是否能够通过i的权值到达j。然后做拓扑图DP。

CODE;int points,edges;int head[MAX],total;int _next[MAXE],aim[MAXE];int length[MAXE],_length[MAXE];inline void Add(int x,int y,int len,int _len){_next[++total] = head[x];aim[total] = y;length[total] = len;_length[total] = _len;head[x] = total;}int _in[MAX];queue<int> q;bool f[MAX][MAXE],g[MAX][MAXE];bool v[MAX];int main(){cin >> points >> edges;for(int x,y,z,l,i = 1; i <= edges; ++i) {scanf(“%d%d%d%d”,&x,&y,&z,&l);Add(x,y,z,l);++_in[y];}for(int i = 1; i <= points; ++i)if(!_in[i])q.push(i);f[1][0] = g[1][0] = true;while(!q.empty()) {int x = q.front(); q.pop();for(int i = head[x]; i; i = _next[i]) {for(int j = 0; j + length[i] < MAXE; ++j) f[aim[i]][j + length[i]] |= f[x][j];for(int j = 0; j + _length[i] < MAXE; ++j) g[aim[i]][j + _length[i]] |= g[x][j];if(!–_in[aim[i]])q.push(aim[i]);}}for(int i = 0 ; i < MAXE; ++i)if(f[points][i]&g[points][i]) {cout << i << endl;return 0;}puts(“IMPOSSIBLE”);return 0;}

生活中最基本的技巧是交流,最可依赖的品质是耐心,

BZOJ 3890 Usaco2015 Jan Meeting Time 拓扑图DP

相关文章:

你感兴趣的文章:

标签云: