Codeforces 19.E Fairy
1.5 seconds
256 megabytes
standard input
standard output
Once upon a time there lived a good fairy A. One day a fine young man B came to her and asked to predict his future. The fairy looked into her magic ball and said that soon the fine young man will meet the most beautiful princess ever and will marry her. Then she drew on a sheet of paper n points and joined some of them with segments, each of the segments starts in some point and ends in some other point. Having drawn that picture, she asked the young man to erase one of the segments from the sheet. Then she tries to colour each point red or blue so, that there is no segment having points of the same colour as its ends. If she manages to do so, the prediction will come true. B wants to meet the most beautiful princess, that's why he asks you to help him. Find all the segments that will help him to meet the princess.
The first input line contains two integer numbers: n — amount of the drawn points and m — amount of the drawn segments (1 ≤ n ≤ 104, 0 ≤ m ≤ 104). The following m lines contain the descriptions of the segments. Each description contains two different space-separated integer numbers v, u (1 ≤ v ≤ n, 1 ≤ u ≤ n) — indexes of the points, joined by this segment. No segment is met in the description twice.
In the first line output number k — amount of the segments in the answer. In the second line output k space-separated numbers — indexes of these segments in ascending order. Each index should be output only once. Segments are numbered from 1 in the input order.
4 4
1 2
1 3
2 4
3 4
4
1 2 3 4
4 5
1 2
2 3
3 4
4 1
1 3
1
5
题目大意:给定一个无向图,问删哪些边之后这个图变成二分图。求的是一个边的集合,实际上只删一条边.
分析:挺好的一道题.
一个图是二分图的充要条件是不存在奇环.将一条奇环上的边删去就能破坏掉这个奇环,如果要破坏掉所有的奇环,那么删的边就必须是所有奇环的交集.
仅仅只是删掉交集这么简单吗?如果一条边同时在偶环和奇环上,删掉这条边后偶环和奇环就会重新组合成一个奇环.那么删的这条边就必须满足两个条件:1.在所有奇环的交集中. 2.不在任何偶环上.
那么找环就好了.天真的我以为直接dfs+栈维护一下就好了.这道题的环是会重叠的,这种做法行不通......换一种做法,每个点记录第一条连向这个点的边的编号(其实记录的就是树边),那么可以把边转换为点,在点上对树边进行操作,非树边需要特判一下.
每次找到一条非树边,这条边连接的两个点是u,v,如果构成了一个奇环,就在维护奇环线段树中把u,v这条链+1,否则在维护偶环线段树中把u,v这条链+1.怎么提取这条链?树链剖分!
最后是一些细节:如果没有奇环,所有的边都满足条件;如果奇环只有1个,那么那个奇环的非树边要考虑进来;维护的是一个图而不是树,在dfs时只考虑树边!
#include <stack>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; const int maxn = ; int n,m,head[maxn],to[maxn],nextt[maxn],id[maxn],tot = ,vis[maxn],cnta,ans,cntb,anss[maxn];
int bianhao[maxn],h[maxn],son[maxn],top[maxn],pos[maxn],sizee[maxn],cnt,fa[maxn],flag;
int L[maxn << ],R[maxn << ],sum1[maxn << ],sum2[maxn << ],tag1[maxn << ],tag2[maxn << ]; struct node
{
int x,y;
}e[maxn]; void add(int x,int y)
{
to[tot] = y;
nextt[tot] = head[x];
head[x] = tot++;
} void dfs1(int u,int faa)
{
h[u] = h[faa] + ;
sizee[u] = ;
fa[u] = faa;
for (int i = head[u];i;i = nextt[i])
{
int v = to[i];
if (v == faa || h[v])
continue;
bianhao[v] = (i / ) + (i % );
vis[(i / ) + (i % )] = ;
dfs1(v,u);
sizee[u] += sizee[v];
if (sizee[v] > sizee[son[u]])
son[u] = v;
}
} void dfs2(int u,int topp)
{
pos[u] = ++cnt;
id[cnt] = u;
top[u] = topp;
if (son[u])
dfs2(son[u],topp);
for (int i = head[u];i;i = nextt[i])
{
int v = to[i];
if (v == fa[u] || v == son[u] || fa[v] != u)
continue;
dfs2(v,v);
}
} void build(int o,int l,int r)
{
L[o] = l;
R[o] = r;
if (l == r)
return;
int mid = (l + r) >> ;
build(o * ,l,mid);
build(o * + ,mid + ,r);
} void pushup(int o)
{
sum1[o] = sum1[o * ] + sum1[o * + ];
sum2[o] = sum2[o * ] + sum2[o * + ];
} void pushdown(int o)
{
if (tag1[o])
{
tag1[o * ] += tag1[o];
tag1[o * + ] += tag1[o];
sum1[o * ] += tag1[o] * (R[o * ] - L[o * ] + );
sum1[o * + ] += tag1[o] * (R[o * + ] - L[o * + ] + );
tag1[o] = ;
}
if (tag2[o])
{
tag2[o * ] += tag2[o];
tag2[o * + ] += tag2[o];
sum2[o * ] += tag2[o] * (R[o * ] - L[o * ] + );
sum2[o * + ] += tag2[o] * (R[o * + ] - L[o * + ] + );
tag2[o] = ;
}
} void update1(int o,int l,int r,int x,int y)
{
if(x <= l && r <= y)
{
sum1[o] += (r - l + );
tag1[o]++;
return;
}
pushdown(o);
int mid = (l + r) >> ;
if (x <= mid)
update1(o * ,l,mid,x,y);
if (y > mid)
update1(o * + ,mid + ,r,x,y);
} void update2(int o,int l,int r,int x,int y)
{
if(x <= l && r <= y)
{
sum2[o] += (r - l + );
tag2[o]++;
return;
}
pushdown(o);
int mid = (l + r) >> ;
if (x <= mid)
update2(o * ,l,mid,x,y);
if (y > mid)
update2(o * + ,mid + ,r,x,y);
} void change(int x,int y,int tagg)
{
if (h[x] < h[y])
swap(x,y);
while (top[x] != top[y])
{
if (h[top[x]] < h[top[y]])
swap(x,y);
int t = top[x];
if (tagg == )
update1(,,n,pos[t],pos[x]);
else
update2(,,n,pos[t],pos[x]);
x = fa[t];
}
if (x == y)
return;
if (h[x] < h[y])
swap(x,y);
if (tagg == )
update1(,,n,pos[y] + ,pos[x]); //为什么要+1?因为实际维护的是边.
else
update2(,,n,pos[y] + ,pos[x]);
} int query1(int o,int l,int r,int v)
{
if (l == r)
return sum1[o];
pushdown(o);
int mid = (l + r) >> ;
if (v <= mid)
return query1(o * ,l,mid,v);
else
return query1(o * + ,mid + ,r,v);
} int query2(int o,int l,int r,int v)
{
if (l == r)
return sum2[o];
pushdown(o);
int mid = (l + r) >> ;
if (v <= mid)
return query2(o * ,l,mid,v);
else
return query2(o * + ,mid + ,r,v);
} int main()
{
scanf("%d%d",&n,&m);
for (int i = ; i <= m; i++)
{
int x,y;
scanf("%d%d",&x,&y);
e[i].x = x;
e[i].y = y;
add(x,y);
add(y,x);
}
for (int i = ; i <= n; i++)
if (!h[i])
dfs1(i,),dfs2(i,i);
build(,,n);
for (int i = ; i <= m; i++)
{
if (!vis[i])
{
int x = e[i].x,y = e[i].y;
if (abs(h[x] - h[y]) % == ) //偶环
{
cntb++;
change(x,y,-);
}
else
{
cnta++;
flag = i;
change(x,y,);
}
}
}
if (cnta == )
{
for (int i = ; i <= m; i++)
anss[++ans] = i;
}
else
{
if (cnta == )
anss[++ans] = flag;
for (int i = ; i <= n; i++)
{
if (query1(,,n,pos[i]) == cnta && query2(,,n,pos[i]) == )
anss[++ans] = bianhao[i];
}
sort(anss + ,anss + + ans);
}
printf("%d\n",ans);
for(int i = ; i <= ans; i++)
printf("%d ",anss[i]);
printf("\n"); return ;
}
Codeforces 19.E Fairy的更多相关文章
- codeforces 19 D. Points(线段树+set二分)
题目链接:http://codeforces.com/contest/19/problem/D 题意:给出3种操作:1)添加点(x,y),2)删除点(x,y),3)查询离(x,y)最近的右上方的点. ...
- Codeforces Round #404 (Div. 2) C. Anton and Fairy Tale 二分
C. Anton and Fairy Tale 题目连接: http://codeforces.com/contest/785/problem/C Description Anton likes to ...
- Codeforces Gym100735 I.Yet another A + B-Java大数 (KTU Programming Camp (Day 1) Lithuania, Birˇstonas, August 19, 2015)
I.Yet another A + B You are given three numbers. Is there a way to replace variables A, B and C with ...
- Codeforces Gym100735 G.LCS Revised (KTU Programming Camp (Day 1) Lithuania, Birˇstonas, August 19, 2015)
G.LCS Revised The longest common subsequence is a well known DP problem: given two strings A and B ...
- Codeforces Gym100735 E.Restore (KTU Programming Camp (Day 1) Lithuania, Birˇstonas, August 19, 2015)
E - Restore Given a matrix A of size N * N. The rows are numbered from 0 to N-1, the columns are num ...
- Educational Codeforces Round 19 A, B, C, E(xjb)
题目链接:http://codeforces.com/contest/797 A题 题意:给出两个数n, k,问能不能将n分解成k个因子相乘的形式,不能输出-1,能则输出其因子: 思路:将n质因分解, ...
- 【19.77%】【codeforces 570D】Tree Requests
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- 【19.46%】【codeforces 551B】ZgukistringZ
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- 【codeforces 785C】Anton and Fairy Tale
[题目链接]:http://codeforces.com/contest/785/problem/C [题意] 容量为n的谷仓,每一天都会有m个谷子入仓(满了就视为m);第i天 会有i只鸟叼走i个谷子 ...
随机推荐
- 随笔1-本想吐槽cnblog编辑器,但是今天猛然发现它竟然这么干净简洁
日常用写作编辑器 多少和我一样有选择综合征的? 不愿意写博客的其中一个非常重要的原因是编辑器不好用! 博客的迁移是相当麻烦的! 所以定下cnblog写东西也是一种勇气!鼓励.... FlashNote ...
- C++ 根据图片url 批量 下载图片
最近需要用到根据图片URL批量下载到本地的操作.查找了相关资料,记录在这儿. 1.首先在CSV文件中提取出url ifstream fin("C:\\Users\\lenovo\\Deskt ...
- ie6下,莫名被复制出一段文字解决
在IE6下使用浮动可能会出现文字重复的情况. 在IE6下,浮动层之间有注释文字的话,之前那个浮动层的内容文字就有可能遭遇一个“隐形”的复制,但是代码里查看文字可并没有多出来. 看个例子: HTML & ...
- listagg wm_concat 行转列
一. 这个写法和wm_concat相似,listagg(day,',')要把哪一列转换为同一行within group (order by day)同一行如何排序 with temp as ( ' d ...
- lintcode-391-数飞机
391-数飞机 给出飞机的起飞和降落时间的列表,用 interval 序列表示. 请计算出天上同时最多有多少架飞机? 注意事项 如果多架飞机降落和起飞在同一时刻,我们认为降落有优先权. 样例 对于每架 ...
- VC++调试基础
一.调试基础 调试快捷键 F5: 开始调试 Shift+F5: 停止调试 F10: 调试到下一句,这里是单步跟踪 F11: 调试到下一句,跟进函数内部 Shift+F11: 从当前函数中跳 ...
- RequestMappingHandlerMapping 详解
我们先理简单梳理一个关系 关系梳理 spring ioc 是spring的核心,用来管理spring bean的生命周期 MVC 是一种使用 MVC(Model View Controller 模型- ...
- linux虚拟机发邮件给163邮件
配置/etc/mail.rc文件 set from=xxxxxxxx@163.com smtp=smtp.163.com set smtp-auth-user=yinhuanyi_cn@163.com ...
- 201621123037 《Java程序设计》第8周学习总结
作业08-集合 1. 本周学习总结 以你喜欢的方式(思维导图或其他)归纳总结集合相关内容. 答: 思维导图: 其他-笔记: 2. 书面作业 1. ArrayList代码分析 1.1 解释ArrayLi ...
- Hadoop环境搭建(三)
长久没用了,再次登陆Ubuntu的时候提醒密码错误,然后就进入了guest session,依然可以进入系统进行工作但身份是guest,于是开始了找回密码的漫漫长路. 首先,在guest模式下,右上角 ...