[HNOI2005]狡猾的商人 ,神奇做法——贪心
2017-12-26 23:18
239 查看
[HNOI2005]狡猾的商人 ,神奇做法——贪心
看到大牛都是写的差分约束或带权并查集,本蒟蒻都不太会(还是用差分约束过了的QAQ),但是想出一种贪心的策略,运用神奇的优先队列实现。思路是:先按左端点为第一排序关键字,再排右端点。之后就开始两两比较,如果左端点相等,就比较右端点,如果相等,就比较值,如果值不同,就直接输出false,否则输出true,如果右端点不等,就把相同的部分抵消掉,把新的区间再压入优先队列。直到不能操作,就输出true。
下附代码:
#include<queue> #include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define N 1100 using namespace std; inline void read(int &x) { x=0; int p=1; char c=getchar(); while(!isdigit(c)){if(c=='-')p=-1;c=getchar();} while(isdigit(c)) {x=(x<<1)+(x<<3)+(c^'0');c=getchar();} x*=p; }//快速读入 int n,m; struct node { int l,r,s; bool operator < (const node &h)const { if(l!=h.l)return l>h.l; return r>h.r; }//重载运算符,确定优先队列的优先级 }tmp; priority_queue<node>q; int main() { int t; read(t); while(t--) { while (!q.empty()) q.pop();//多组数据清空 read(n);read(m); if(m==1){printf("true\n");continue;}//其实没必要特判,只是优化一点点 for(int i=1;i<=m;i++) { int l,r,s; read(tmp.l);read(tmp.r);read(tmp.s); 4000 q.push(tmp); } tmp=q.top();//取出第一个 q.pop(); while(!q.empty()) { node tmp1; tmp1=q.top(); q.pop(); if(tmp.l==tmp1.l) { if(tmp.r==tmp1.r) { if(tmp.s!=tmp1.s) {printf("false\n");goto end;}//退出多重循环的小操作 } else if(tmp.r<tmp1.r) q.push((node) {tmp.r+1, tmp1.r, tmp1.s - tmp.s});//将抵消后的部分放入队列 } tmp = tmp1;//继续比 } printf("true\n"); end:; } return 0; }
相关文章推荐
- BZOJ1202 [HNOI2005]狡猾的商人 并查集+前缀和
- bzoj1202 [HNOI2005]狡猾的商人
- bzoj 1202 [HNOI2005]狡猾的商人
- bzoj1202: [HNOI2005]狡猾的商人(带权并查集)
- BZOJ 1202: [HNOI2005]狡猾的商人
- [BZOJ1202][HNOI2005]狡猾的商人(并查集)
- [BZOJ]1202: [HNOI2005]狡猾的商人 带权并查集
- [BZOJ1202][HNOI2005]狡猾的商人(并查集+前缀和)
- bzoj 1202: [HNOI2005]狡猾的商人
- 1202: [HNOI2005]狡猾的商人
- 1202: [HNOI2005]狡猾的商人 带权并查集
- 1202: [HNOI2005]狡猾的商人
- BZOJ 1202: [HNOI2005]狡猾的商人(并查集)
- 1202: [HNOI2005]狡猾的商人
- bzoj1202:[HNOI2005]狡猾的商人 【并查集】
- 【bzoj1202】 HNOI2005狡猾的商人 并查集
- 【BZOJ 1202】 [HNOI2005]狡猾的商人 (加权并查集)
- BZOJ 1202: [HNOI2005]狡猾的商人【并查集】【路径迭代】
- 【BZOJ1202】【HNOI2005】狡猾的商人
- bzoj 1202: [HNOI2005]狡猾的商人(带权并查集)