POJ

来源:互联网 发布:星际战甲画质优化 编辑:程序博客网 时间:2024/05/21 05:39

传送门:POJ - 3190 

题意:给定n个区间,问至少把他们分成几个集合,才能使集合内的区间互不相交,并输出每个区间对应的集合编号。

思路:开始写了一发暴力,用并查集维护了一下,然而还是无情的tle。

正解:将区间按左端点排序,然后遍历,用优先队列维护已经遍历过的区间的右端点,当前区间的左端点比堆顶的右端点小的话就说明能加到同一个集合里,否则就要新开一个集合。

代码:

#include<iostream>#include<stdio.h>#include<algorithm>#include<queue>#define ll long long#define pb push_back#define fi first#define se second#define pi acos(-1)#define inf 0x3f3f3f3f#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1#define rep(i,x,n) for(int i=x;i<n;i++)#define per(i,n,x) for(int i=n;i>=x;i--)using namespace std;typedef pair<int,int>P;const int MAXN=100010;int gcd(int a,int b){return b?gcd(b,a%b):a;}struct node{int l, r, id;bool operator < (node a) const{return r > a.r;}}p[MAXN];priority_queue<node> q;bool cmp(node a, node b){return a.l < b. l;}int ans[MAXN];int main(){int n;while(cin >> n){while(!q.empty()) q.pop();for(int i = 1; i <= n; i++){scanf("%d %d", &p[i].l, &p[i].r);p[i].id = i;}int cnt = 0;sort(p + 1, p + n + 1, cmp);for(int i = 1; i <= n; i++){if(q.empty() || q.top().r >= p[i].l)q.push(p[i]), ans[p[i].id] = ++cnt;elseans[p[i].id] = ans[q.top().id], q.pop(), q.push(p[i]);}cout << cnt <<endl;for(int i = 1; i <= n; i++)printf("%d\n", ans[i]);} return 0;}



暴力代码:

#include<iostream>#include<stdio.h>#define ll long long#define pb push_back#define fi first#define se second#define pi acos(-1)#define inf 0x3f3f3f3f#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1#define rep(i,x,n) for(int i=x;i<n;i++)#define per(i,n,x) for(int i=n;i>=x;i--)using namespace std;typedef pair<int,int>P;const int MAXN=100010;int gcd(int a,int b){return b?gcd(b,a%b):a;}P p[MAXN];int f[MAXN];int getf(int k){return k == f[k] ? k : f[k] = getf(f[k]);}int ans[MAXN];int main(){int n;while(cin >> n){for(int i = 1; i <= n; i++){scanf("%d %d", &p[i].fi, &p[i].se);f[i] = i;}f[n + 1] = n + 1;int last = 0, cnt = 0;for(int i = 1; i <= n; i = getf(i + 1)){last = 0;for(int j = getf(i); j <= n; j = getf(j + 1)){if(p[j].fi > last){ans[j] = cnt + 1;last = p[j].se, f[j] = getf(j + 1);}}cnt++;}cout << cnt << endl;for(int i = 1; i <= n; i++)printf("%d\n", ans[i]);} return 0;}



原创粉丝点击