题上的中文题意太不明确了。。。
给出一个拓扑图,每条有向边有两个权值,有两个人从1出发到n,分别走这两种权值。问有没有权值使得这两个人都能走过这些权值到达n。
看懂了题之后就水了。维护两个数组表示从1号节点是否能够通过i的权值到达j。然后做拓扑图DP。
#define _CRT_SECURE_NO_WARNINGS
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 110
#define MAXE 10010
#define INF 0x3f3f3f3f
using namespace std;
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
原文地址:http://blog.csdn.net/jiangyuze831/article/details/44019719