您的位置:首页 > 其它

【HDOJ】2155 小黑的镇魂曲

2015-12-29 17:16 399 查看
线段树+SPFA最短路可以过。或者DP也能过。
需要注意的是xl的范围是错的,测试用例中xl可能为0,他妈的,因为这个一直莫名其妙的wa。
1. spfa建图增加一倍的点即可(讨论左端点和右端点)。

/* 2155 */
#include <iostream>
#include <sstream>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#include <deque>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <climits>
#include <cctype>
#include <cassert>
#include <functional>
#include <iterator>
#include <iomanip>
using namespace std;
//#pragma comment(linker,"/STACK:102400000,1024000")

#define sti                set<int>
#define stpii            set<pair<int, int> >
#define mpii            map<int,int>
#define vi                vector<int>
#define pii                pair<int,int>
#define vpii            vector<pair<int,int> >
#define rep(i, a, n)     for (int i=a;i<n;++i)
#define per(i, a, n)     for (int i=n-1;i>=a;--i)
#define clr                clear
#define pb                 push_back
#define mp                 make_pair
#define fir                first
#define sec                second
#define all(x)             (x).begin(),(x).end()
#define SZ(x)             ((int)(x).size())
#define lson            l, mid, rt<<1
#define rson            mid+1, r, rt<<1|1

typedef struct {
int v, w, nxt;
} edge_t;

typedef struct node_t {
int xl, xr, y;

node_t() {}
node_t(int xl, int xr, int y):
xl(xl), xr(xr), y(y) {}

friend bool operator <(const node_t& a, const node_t& b) {
return a.y < b.y;
}

} node_t;

const int maxv = 1025;
const int maxe = maxv * 1000;
const int INF = 0x3f3f3f3f;
int n, x, y, mx, T;
edge_t E[maxe];
int head[maxv<<1];
bool visit[maxv<<1];
int dis[maxv<<1];
node_t nd[maxv];
int l = 0, m;
int start, End;
int ID[maxv<<2];
int L, R, id;

void init() {
l = 0;
m = 1;
memset(head, -1, sizeof(head));
}

void addEdge(int u, int v, int w) {
E[l].v = v;
E[l].w = w;
E[l].nxt = head[u];
head[u] = l++;
}

void Build(int l, int r, int rt) {
ID[rt] = 0;
if (l == r)
return ;

int mid = (l + r) >> 1;
Build(lson);
Build(rson);
}

inline void PushDown(int rt) {
if (ID[rt]) {
ID[rt<<1] = ID[rt<<1|1] = ID[rt];
ID[rt] = 0;
}
}

void Update(int l, int r, int rt) {
if (L<=l && R>=r) {
ID[rt] = id;
return ;
}

PushDown(rt);
int mid = (l + r) >> 1;

if (R <= mid) {
Update(lson);
} else if (L > mid) {
Update(rson);
} else {
Update(lson);
Update(rson);
}
}

int Query(int k, int l, int r, int rt) {
if (l == r)
return ID[rt];

PushDown(rt);
int mid = (l + r) >> 1;

if (k <= mid)
return Query(k, lson);
else
return Query(k, rson);
}

int spfa() {
queue<int> Q;
int u, v, k;

memset(visit, false, sizeof(visit));
memset(dis, INF, sizeof(dis));
dis[start] = 0;
visit[start] = true;
Q.push(start);

while (!Q.empty()) {
u = Q.front();
Q.pop();
visit[u] = false;
for (k=head[u]; k!=-1; k=E[k].nxt) {
v = E[k].v;
if (dis[u]+E[k].w < dis[v]) {
dis[v] = dis[u] + E[k].w;
if (!visit[v]) {
visit[v] = true;
Q.push(v);
}
}
}
}

return dis[End];
}

int main() {
ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif

int t;
int lid, rid;
int tmp, w;

scanf("%d", &t);
rep(tt, 1, t+1) {
scanf("%d %d %d %d %d", &n, &x, &y, &mx, &T);
++x;
init();
rep(i, 0, n) {
scanf("%d %d %d", &nd[m].xl, &nd[m].xr, &nd[m].y);
++nd[m].xl;
++nd[m].xr;
if (nd[m].y < y)
++m;
}

nd[m].xl = x;
nd[m].xr = x;
nd[m].y = y;
++m;
nd[m].xl = 1;
nd[m].xr = 1002;
nd[m].y = 0;
sort(nd+1, nd+1+m);
End = 1;
start = m;
memset(ID, 0, sizeof(ID));

L = nd[1].xl;
R = nd[1].xr;
id = 1;
Update(1, 1005, 1);
rep(i, 2, m+1) {

// handle left
L = nd[i].xl;
lid = Query(L, 1, 1005, 1);
tmp = nd[i].y - nd[lid].y;
if (tmp <= mx) {
if (lid == End) {
w = tmp;
addEdge(i, lid, w);
} else {
// to left of lid
w = tmp + nd[i].xl - nd[lid].xl;
addEdge(i, lid, w);

// to right of lid
w = tmp + nd[lid].xr - nd[i].xl;
addEdge(i, lid+m, w);
}
}

// handle right
if (i != m) {
R = nd[i].xr;
rid = Query(R, 1, 1005, 1);
tmp = nd[i].y - nd[rid].y;
if (tmp <= mx) {
if (rid == End) {
w = tmp;
addEdge(i+m, rid, w);
} else {
// to left of rid
w = tmp + nd[i].xr - nd[rid].xl;
addEdge(i+m, rid, w);

// to right of rid
w = tmp + nd[rid].xr - nd[i].xr;
addEdge(i+m, rid+m, w);
}
}
}

L = nd[i].xl;
R = nd[i].xr;
id = i;

Update(1, 1005, 1);
}

tmp = spfa();
if (tmp==INF || tmp>T)
puts("YES");
else
puts("NO");
}

#ifndef ONLINE_JUDGE
printf("time = %d.\n", (int)clock());
#endif

return 0;
}


2. DP, 二维DP,没什么好说的。

/* 2155 */
#include <iostream>
#include <sstream>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#include <deque>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <climits>
#include <cctype>
#include <cassert>
#include <functional>
#include <iterator>
#include <iomanip>
using namespace std;
//#pragma comment(linker,"/STACK:102400000,1024000")

#define sti                set<int>
#define stpii            set<pair<int, int> >
#define mpii            map<int,int>
#define vi                vector<int>
#define pii                pair<int,int>
#define vpii            vector<pair<int,int> >
#define rep(i, a, n)     for (int i=a;i<n;++i)
#define per(i, a, n)     for (int i=n-1;i>=a;--i)
#define clr                clear
#define pb                 push_back
#define mp                 make_pair
#define fir                first
#define sec                second
#define all(x)             (x).begin(),(x).end()
#define SZ(x)             ((int)(x).size())
#define lson            l, mid, rt<<1
#define rson            mid+1, r, rt<<1|1

typedef struct node_t {
int l, r, h;

node_t() {}
node_t(int l, int r, int h):
l(l), r(r), h(h) {}

friend bool operator< (const node_t& a, const node_t& b) {
return a.h > b.h;
}

} node_t;

const int maxn = 1005;
const int INF = 0x3f3f3f3f;
node_t nd[maxn];
int dp[maxn][2];
int n, x, y, mx, T;

void solve() {
bool fl, fr;
int tmp;

memset(dp, INF, sizeof(dp));
dp[0][0] = dp[0][1] = 0;
rep(i, 0, n) {
#ifndef ONLINE_JUDGE
printf("l = %d, r = %d, [0] = %d, [1] = %d\n", nd[i].l, nd[i].r, dp[i][0], dp[i][1]);
#endif
fl = fr = true;
rep(j, i+1, n+1) {
tmp = nd[i].h - nd[j].h;
if (tmp > mx)
break;
if (fl && nd[j].l<=nd[i].l && nd[i].l<=nd[j].r) {
fl = false;
if (j == n) {
dp[j][0] = min(dp[j][0], dp[i][0]+tmp);
dp[j][1] = min(dp[j][1], dp[i][0]+tmp);
} else {
dp[j][0] = min(dp[j][0], dp[i][0]+tmp+nd[i].l-nd[j].l);
dp[j][1] = min(dp[j][1], dp[i][0]+tmp+nd[j].r-nd[i].l);
}
}
if (fr && nd[j].l<=nd[i].r && nd[i].r<=nd[j].r) {
fr = false;
if (j == n) {
dp[j][0] = min(dp[j][0], dp[i][1]+tmp);
dp[j][1] = min(dp[j][1], dp[i][1]+tmp);
} else {
dp[j][0] = min(dp[j][0], dp[i][1]+tmp+nd[i].r-nd[j].l);
dp[j][1] = min(dp[j][1], dp[i][1]+tmp+nd[j].r-nd[i].r);
}
}
}
}

if (dp
[0]<=T || dp
[1]<=T)
puts("NO");
else
puts("YES");
}

int main() {
ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif

int t;

scanf("%d", &t);
while (t--) {
scanf("%d %d %d %d %d", &n, &x, &y, &mx, &T);
nd[0].l = nd[0].r = x;
nd[0].h = y;
rep(i, 1, n+1)
scanf("%d %d %d", &nd[i].l, &nd[i].r, &nd[i].h);
sort(nd, nd+n);
++n;
nd
.l = 0;
nd
.r = 1010;
nd
.h = 0;
solve();
}

#ifndef ONLINE_JUDGE
printf("time = %d.\n", (int)clock());
#endif

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: