zoukankan      html  css  js  c++  java
  • bzoj4423[AMPPZ2013]Bytehattan

    bzoj4423[AMPPZ2013]Bytehattan

    题意:

    n*n的顶点图,一开始相邻顶点均有边相连,现在删掉k条边,希望知道每次删边后边的两个端点是否联通。n≤1500,k≤2*n*(n-1),边最多被删一次。

    题解:

    隐隐觉得是并查集,但不知道删边怎么表示。在膜拜了题解后明白原来可以转成对偶图(以格子和外框为节点),原图的删边就是新图的加边。每次新图加边时就判断是否会产生环,若会,说明原图的两个端点在删边后不连通。

    代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #define maxn 2000
     5 #define inc(i,j,k) for(int i=j;i<=k;i++)
     6 using namespace std;
     7 
     8 int pos[maxn][maxn],fa[2*maxn*maxn],tot,n,k,x[2],y[2]; bool ans; char s[2][5];
     9 inline int read(){
    10     char ch=getchar(); int f=1,x=0;
    11     while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
    12     while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    13     return f*x;
    14 }
    15 int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
    16 int main(){
    17     n=read(); k=read(); tot=0; inc(i,1,n-1)inc(j,1,n-1)pos[i][j]=++tot; inc(i,1,tot)fa[i]=i;
    18     inc(i,1,k){
    19         x[0]=read(),y[0]=read(); scanf("%s",s[0]); x[1]=read(),y[1]=read(); scanf("%s",s[1]);
    20         if(s[ans][0]=='N'){
    21             int a=find(pos[x[ans]-1][y[ans]]),b=find(pos[x[ans]][y[ans]]);
    22             if(a==b)ans=1;else fa[a]=b,ans=0;
    23         }
    24         else{
    25             int a=find(pos[x[ans]][y[ans]-1]),b=find(pos[x[ans]][y[ans]]);
    26             if(a==b)ans=1;else fa[a]=b,ans=0;
    27         }
    28         if(!ans)puts("TAK");else puts("NIE");
    29     }
    30     return 0;
    31 }

    20160724

  • 相关阅读:
    快速排序
    冒泡排序算法
    设计模式之工厂方法模式
    调用存储过程修改
    取出字符串中的回车空格
    调用存储过程实例
    C++左值
    cocos2d-x 不规则形状按钮的点击判定
    C/C++
    字符函数库 cctype
  • 原文地址:https://www.cnblogs.com/YuanZiming/p/5701719.html
Copyright © 2011-2022 走看看