JZOJ3845. 【NOIP2014八校联考第1场第1试9.20】简单题(simple)
2018-02-08 11:54
489 查看
Description
dzy 手上有一张n 个点m 条边的联通无向图,仙人掌是一张每条边最多在一个简单环内的联通无向图。他想求这个无向图的生成仙人掌中最多有多少条边。但是dzy 觉得这个问题太简单了,于是他定义了“美丽的生成仙人掌”,即在一个生成仙人掌中如果满足对于任意编号为i,j(i < j) 的两点,存在一条它们之间的简单路径上面有j-i+1 个点,则这个仙人掌是美丽的。
他现在想要知道这张图的美丽的生成仙人掌中最多有多少条边,你能帮帮他吗?
Input
第一行两个整数n,m。接下来m 行每行两个整数ui,vi,表示这两个点之间有一条无向边。保证图中没有自环。Output
仅一行一个整数表示答案。Sample Input
2 11 2
Sample Output
1Data Constraint
对于10% 的数据,n <=10。对于30% 的数据,n <=10^3。
对于100% 的数据,n <=10^5,m <= 2n。
题解
先考虑如何满足对于任意编号为i,j(i < j) 的两点,存在一条它们之间的简单路径上面有j-i+1 个点这个要求。很显然唯一能满足的就是一条链,且链上面点的编号都是连续的。
现在就要构造边数最多的仙人掌了。
两个环是不能相交的,但可以相切。
问题就转化成了线段覆盖问题,
在一条连续的链[l,r]中,
有一些线段xi,yi,l≤xi<yi≤r
要求线段不能重复覆盖,是的选取的线段尽可能多。
一个简单的dp就可以了,
是fi表示前面i个位置都已经处理完了(不一定都不线段覆盖)的最多边数。
code
#include<queue> #include<cstdio> #include<iostream> #include<algorithm> #include <cstring> #include <string.h> #include <cmath> #include <math.h> #include <time.h> #define ll long long #define N 100003 #define M 103 #define db double #define P putchar #define G getchar #define inf 998244353 using namespace std; char ch; void read(int &n) { n=0; ch=G(); while((ch<'0' || ch>'9') && ch!='-')ch=G(); ll w=1; if(ch=='-')w=-1,ch=G(); while('0'<=ch && ch<='9')n=(n<<3)+(n<<1)+ch-'0',ch=G(); n*=w; } int max(int a,int b){return a>b?a:b;} int min(int a,int b){return a<b?a:b;} ll abs(ll x){return x<0?-x:x;} ll sqr(ll x){return x*x;} void write(ll x){if(x>9) write(x/10);P(x%10+'0');} int nxt[N<<2],to[N<<2],lst ,tot; int n,m,x,y,cnt,l,r,f ,ans; bool p ; struct node { int x,y; }a[N<<2]; bool cmp(node a,node b) { return a.x<b.x || (a.x==b.x && a.y<b.y); } void ins(int x,int y) { nxt[++tot]=lst[x]; to[tot]=y; lst[x]=tot; } int main() { read(n);read(m); for(int i=1;i<=m;i++) { read(x),read(y),ins(x,y),ins(y,x); if(x>y)swap(x,y); if(x+1==y)p[x]=1; } for(l=1;r<=n;l=r+1) { cnt=0; for(r=l;p[r];r++); for(int i=l;i<=r;i++) for(int j=lst[i];j;j=nxt[j]) if(l<=to[j] && to[j]<=r && abs(to[j]-i)>1)a[++cnt].x=i,a[cnt].y=to[j]; sort(a+1,a+1+cnt,cmp); f[a[0].x=l]=0; for(int i=1;i<=cnt;i++) { for(int j=a[i-1].x+1;j<=a[i].x;j++) f[j]=max(f[j],f[j-1]); f[a[i].y]=f[a[i].x]+1; } for(int i=a[cnt].x+1;i<=r;i++) f[i]=max(f[i],f[i-1]); ans=max(ans,f[r]+r-l+1); } write(ans); return 0; }
相关文章推荐
- JZOJ 3845. 【NOIP2014八校联考第1场第1试9.20】简单题
- 【NOIP2014八校联考第1场第1试9.20】简单题
- 【NOIP2014八校联考第1场第1试9.20】统计损失(count)(树形dp)
- 【JZOJ3870】【NOIP2014八校联考第4场第1试10.19】单词检索(search)
- JZOJ3847. 【NOIP2014八校联考第1场第2试9.21】都市环游(travel)
- 【JZOJ3872】【NOIP2014八校联考第4场第1试10.19】圣诞树(tree)
- JZOJ 3870. 【NOIP2014八校联考第4场第1试10.19】单词检索(search)
- 【JZOJ3871】【NOIP2014八校联考第4场第1试10.19】无聊的游戏(game)
- JZOJ 3871. 【NOIP2014八校联考第4场第1试10.19】无聊的游戏(game)
- JZOJ 3871. 【NOIP2014八校联考第4场第1试10.19】无聊的游戏(game)
- JZOJ3870. 【NOIP2014八校联考第4场第1试10.19】单词检索(search)
- JZOJ 3875. 【NOIP2014八校联考第4场第2试10.20】星球联盟(alliance)
- 【JZOJ3853】【NOIP2014八校联考第2场第2试9.28】帮助Bsny(help)
- 【NOIP2014八校联考第1场第2试9.21】大水题(water)
- {题解}[jzoj3853]【NOIP2014八校联考第2场第2试9.28】帮助Bsny(help)
- [JZOJ]3856. 【NOIP2014八校联考第3场第1试10.4】规避
- 【JZOJ3852】【NOIP2014八校联考第2场第2试9.28】单词接龙(words)
- 【NOIP2014八校联考第1场第2试】大水题(water)
- 【JZOJ3852】【spfa判负环】【NOIP2014八校联考第2场第2试9.28】单词接龙(words)
- jzoj. 3873. 【NOIP2014八校联考第4场第2试10.20】乐曲创作(music)