标签:style blog http io color os ar for sp
题意:给定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 }
标签:style blog http io color os ar for sp
原文地址:http://www.cnblogs.com/yzcstc/p/4063604.html