首页 > 代码库 > codeforces 429E
codeforces 429E
题意:给定n<=100000线段[l,r],然后给这些线段染色(red or blue),求最后平面上任意一个点被蓝色及红色覆盖次数只差的绝对值不大于1
思路:把每条线段拆成2个点[l<<1, r<<1|1]来表示,
那么如果把染red看成1,blue看成-1
那么对于每条线段染色为v(-1 or 1),等价于l<<1点为v,r<<1|1为-v,
则题目等价于求一种合法的方案使得任意点的abs(前缀和S)<=1
此外,由于任一点取值为 -1 or 1,并且过程中abs(S)<=1,所以任意奇数位置(下标从0开始)的前缀和为0
所以转化为图论模型,就是经典的二分图染色模型:
对于每个线段两端连一条边;
对于排序后相邻的(i<<1, i <<1|1)连一条边,
又由于图的特殊性不会出现奇数环。。
因为对于任意的一个点,只有两条边,并且这两条边类型不同,不妨设为A和B。
那么如果出现了环,那么路径上肯定是ABAB交替出现,并且是偶数。。因为出现奇环必有路径上出现重复的AA或者BB,显然这种情况是不会出现的。。
code:
1 /* 2 * Author: Yzcstc 3 * Created Time: 2014/10/30 19:12:23 4 * File Name: cf429.cpp 5 */ 6 #include<cstdio> 7 #include<iostream> 8 #include<cstring> 9 #include<cstdlib>10 #include<cmath>11 #include<algorithm>12 #include<string>13 #include<map>14 #include<set>15 #include<vector>16 #include<queue>17 #include<stack>18 #include<ctime>19 using namespace std;20 vector<int> e[210000];21 int col[210000], n;22 pair<int, int> p[210000];23 void dfs(int u, int color){24 if (col[u] != -1) return;25 col[u] = color;26 for (int i = 0; i < (int)e[u].size(); ++i)27 dfs(e[u][i], color^1); 28 }29 30 void solve(){31 for (int i = 0; i <= n * 2; ++i) e[i].clear();32 int l, r;33 for (int i = 0; i < n; ++i){34 scanf("%d%d", &l, &r);35 e[i<<1].push_back(i<<1|1), e[i<<1|1].push_back(i<<1);36 p[i<<1] = make_pair(l<<1,i<<1), p[i<<1|1] = make_pair(r<<1|1, i<<1|1);37 }38 sort(p, p + 2*n);39 for (int i = 0; i < n; ++i){40 int x = p[i<<1].second, y = p[i<<1|1].second;41 e[x].push_back(y), e[y].push_back(x);42 }43 memset(col, -1, sizeof(col));44 for (int i = 0; i < n; ++i){45 if (col[i<<1] == -1) dfs(i<<1, 0);46 printf("%d ", col[i<<1]);47 }48 }49 50 int main(){51 // freopen("a.in", "r", stdin);52 // freopen("a.out", "w", stdout);53 while (scanf("%d", &n) != EOF){54 solve();55 }56 return 0;57 }
codeforces 429E
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。