首页 > 其他 > 详细

BZOJ 3890 Usaco2015 Jan Meeting Time 拓扑图DP

时间:2015-03-02 16:50:40      阅读:652      评论:0      收藏:0      [点我收藏+]

题目大意

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

思路

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

CODE

#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

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!