博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
bzoj3562: [SHOI2014]神奇化合物
阅读量:4604 次
发布时间:2019-06-09

本文共 2410 字,大约阅读时间需要 8 分钟。

又是玄学的一天~

首先,这题做法就很玄学,考虑到点和询问都很少,那么很多边都是没有改动的,那么可以离线用并查集缩点,然后爆搜求解。

假如只是这样还好吧,尴尬就在于我跑数据前面3个点挂了??黑人问号

然后一怒之下特判,假如边数<10000那我就不缩点,直接爆力搞!

A了~ 真的A了。。。

这个故事告诉我们,猜证结合,爆正乱搞,天下大同。。。

#include
#include
#include
#include
#include
#include
using namespace std;int n,m;struct init{ int x,y,op;}h[210000],q[11000];int hlen,qlen;bool pc[5100][5100];char ss[10];void sc(){ hlen=0; memset(pc,false,sizeof(pc)); for(int i=1;i<=m;i++) { int x,y; scanf("%d%d",&x,&y); if(pc[x][y]==false) { pc[x][y]=true;pc[y][x]=true; hlen++; h[hlen].x=x,h[hlen].y=y; } } scanf("%d",&qlen); for(int i=1;i<=qlen;i++) { scanf("%s",ss+1); if(ss[1]=='A') { scanf("%d%d",&q[i].x,&q[i].y),q[i].op=1; pc[q[i].x][q[i].y]=false; pc[q[i].y][q[i].x]=false; } else if(ss[1]=='D') { scanf("%d%d",&q[i].x,&q[i].y),q[i].op=2; pc[q[i].x][q[i].y]=false; pc[q[i].y][q[i].x]=false; } else q[i].op=3; }}int fa[5100];int findfa(int x){ if(fa[x]==x)return x; fa[x]=findfa(fa[x]);return fa[x];}void shrink(){ for(int i=1;i<=n;i++)fa[i]=i; if(m>10000) { for(int x=1;x<=n;x++) for(int y=1;y<=n;y++) if(pc[x][y]==true) { int fx=findfa(x),fy=findfa(y); if(fx!=fy)fa[fx]=fy; } }}//-----------init------------------------struct node{ int x,y,next;bool ch;}a[4100000];int len,last[5100];int eid[5100][5100];void ins(int x,int y){ len++; a[len].x=x;a[len].y=y; a[len].next=last[x];last[x]=len; a[len].ch=false; eid[x][y]=len;}void cut(int x,int y){ if(eid[x][y]!=-1) { a[eid[x][y]].ch=true; eid[x][y]=-1; }}//------------edge------------------------int tim,v[5100];void dfs(int x){ v[x]=tim; for(int k=last[x];k;k=a[k].next) { if(a[k].ch==false) { int y=a[k].y; if(v[y]!=tim)dfs(y); } }}int main(){ freopen("compound.in","r",stdin); freopen("compound.out","w",stdout); scanf("%d%d",&n,&m); sc();shrink(); memset(eid,-1,sizeof(eid)); for(int i=1;i<=hlen;i++) { int x=findfa(h[i].x),y=findfa(h[i].y); if(x!=y&&eid[x][y]==-1) ins(x,y), ins(y,x); } tim=0;memset(v,0,sizeof(v)); for(int i=1;i<=qlen;i++) { if(q[i].op==1) { int x=findfa(q[i].x),y=findfa(q[i].y); if(eid[x][y]==-1) ins(x,y),ins(y,x); } else if(q[i].op==2) { int x=findfa(q[i].x),y=findfa(q[i].y); cut(x,y),cut(y,x); } else { int ans=0;tim++; for(int i=1;i<=n;i++) { int x=findfa(i); if(v[x]!=tim) dfs(x), ans++; } printf("%d\n",ans); } } return 0;}

 

转载于:https://www.cnblogs.com/AKCqhzdy/p/8782557.html

你可能感兴趣的文章
块设备驱动程序
查看>>
每日一记======>linux U盘格式化 2012.08.27
查看>>
Unsafe类park,unpark详解
查看>>
A Simple Example About Privileged Methods in JavaScript
查看>>
Dynamics CRM Microsoft SQL Server 指定的数据库具有更高的版本号
查看>>
pm2进阶使用
查看>>
在c++中,静态数据成员可以被非静态成员函数调用吗?如果可以调用的话那为什么还要定义静态成员函数呢...
查看>>
查看Sql Server所有表占用的空间大小
查看>>
CSS重置(css reset)【转载】
查看>>
Elasticserach 配置文件详解
查看>>
【案例】大型摩托制造企业如何高效排产?看APS系统如何帮忙
查看>>
NTCIR-13 We Want Web 任务概述
查看>>
模版include的用法
查看>>
LotusScript_导出数据库路径和名称
查看>>
String ,StringBuffer 与S tringBuilder的区别??
查看>>
PgSQL · 追根究底 · WAL日志空间的意外增长
查看>>
struts2笔记之struts:property标签
查看>>
Threejs.教程
查看>>
超闩锁和子闩锁如何工作的
查看>>
ZendStudio快捷键
查看>>