zoukankan      html  css  js  c++  java
  • 5月12日

    poj1182

    题意:http://poj.org/problem?id=1182

    分析:并查集的经典题目,在这题当中,我们不仅要用并查集维护属于同一类,同时还应该用并查集维护被吃的关系。因为物种属于A,B,C三种,所以我们开一个n*3来进行纪录。然后如果是1的话,那分别合并到三个集合,如果是2的话,按照食物链的关系进行合并。注意在合并之前我们需要进行判断,如果是1的话,要判断该元素是否在另外两类中出现过,如果是2的话,要判断食物链是否有矛盾。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <string>
     5 #include <vector>
     6 #include <algorithm>
     7 #include <set>
     8 #include <map>
     9 #include <bitset>
    10 #include <cmath>
    11 #include <queue>
    12 #include <stack>
    13 using namespace std;
    14 const int maxn=50002;
    15 int par[maxn*3],rankl[maxn*3];
    16 
    17 //并查集模板
    18 void init(int n){
    19     for(int i=0;i<n;i++){    //初始化
    20         par[i]=i;
    21         rankl[i]=0;
    22     }
    23 }
    24 
    25 int findl(int x){   //查找跟结点
    26     if(x==par[x]){
    27         return x;
    28     }else{
    29         return par[x]=findl(par[x]);
    30     }
    31 }
    32 
    33 void unite(int x,int y){   //合并操作
    34     x=findl(x);
    35     y=findl(y);
    36     if(x==y) return;
    37     if(rankl[x]<rankl[y]){
    38         par[x]=y;
    39     }else{
    40         par[y]=x;
    41         if(rankl[x]==rankl[y])   rankl[x]++;
    42     }
    43 }
    44 
    45 bool same(int x,int y){   //判断是否在同一集合
    46     return findl(x)==findl(y);
    47 }
    48 
    49 int main()
    50 {
    51     int n,k;
    52     cin>>n>>k;
    53     init(n*3);
    54     int cnt=0;
    55     for(int i=0;i<k;i++){
    56         int id,x,y;
    57         scanf("%d%d%d",&id,&x,&y);
    58         --x,--y;
    59         if(x<0||y<0||n<=x||n<=y){
    60             cnt++; continue;
    61         }
    62         if(id==1){
    63             if(same(x,y+n)||same(x,y+2*n)){
    64                 cnt++;
    65             }else{
    66                 unite(x,y);
    67                 unite(x+n,y+n);
    68                 unite(x+2*n,y+2*n);
    69             }
    70         }else{
    71             if(same(x,y)||same(x,y+2*n)){
    72                 cnt++;
    73             }else{
    74                 unite(x,y+n);
    75                 unite(x+n,y+2*n);
    76                 unite(x+2*n,y);
    77             }
    78         }
    79     }
    80     cout<<cnt<<endl;
    81     return 0;
    82 }
    View Code

    poj2236

    题意:因为地震,使网络不能联通,经过维修之后可以连通不超过距离d的网络,任何网络可以作为其他两个网络的中介。O表示维修,S表示是否连通

    分析:裸的并查集,O的时候把符合要求的并入集合,S的时候看是否属于同一个集合即可。注意不行的时候是FAIL,2333

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <string>
     5 #include <vector>
     6 #include <algorithm>
     7 #include <set>
     8 #include <map>
     9 #include <bitset>
    10 #include <cmath>
    11 #include <queue>
    12 #include <stack>
    13 using namespace std;
    14 const int maxn=1010;
    15 int par[maxn],rankl[maxn];
    16 
    17 void init(int n){
    18     for(int i=0;i<=n;i++){
    19         par[i]=i;
    20         rankl[i]=0;
    21     }
    22 }
    23 
    24 int findl(int x){
    25     if(x==par[x])
    26         return x;
    27     else{
    28         return par[x]=findl(par[x]);
    29     }
    30 }
    31 
    32 void unite(int x,int y){
    33     x=findl(x);
    34     y=findl(y);
    35     if(x==y)  return;
    36     if(rankl[x]<rankl[y]){
    37         par[x]=y;
    38     }else{
    39         par[y]=x;
    40         if(rankl[x]==rankl[y])  rankl[x]++;
    41     }
    42 }
    43 
    44 bool same(int x,int y){
    45     return findl(x)==findl(y);
    46 }
    47 
    48 int n,d;
    49 bool judge(int x1,int y1,int x2,int y2){
    50     if((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)>d*d)
    51         return false;
    52     else return true;
    53 }
    54 
    55 struct p{
    56     int id,x,y,vis;
    57 }s[maxn];
    58 int main()
    59 {
    60     cin>>n>>d;
    61     init(n);
    62     for(int i=1;i<=n;i++){
    63         cin>>s[i].x>>s[i].y;
    64         s[i].id=i;
    65         s[i].vis=0;
    66     }
    67     char ch[5];
    68     while(scanf("%s",ch)!=EOF){
    69         int a,b;
    70         if(ch[0]=='O'){
    71             cin>>a;
    72             s[a].vis=1;
    73             for(int i=1;i<=n;i++){
    74                 if(judge(s[i].x,s[i].y,s[a].x,s[a].y)&&s[i].vis&&i!=a)
    75                     unite(i,a);
    76             }
    77         }else if(ch[0]=='S'){
    78             cin>>a>>b;
    79             if(same(a,b))
    80                 cout<<"SUCCESS"<<endl;
    81             else
    82                 cout<<"FAIL"<<endl;
    83         }
    84     }
    85     return 0;
    86 }
    View Code
  • 相关阅读:
    Servlet中request乱码问题解决
    java对cookie的操作
    EL表达式
    MYSQL安装以及卸载 -- WINDOWS
    java接口
    HttpClient配置及运用(二)
    JVM的内存空间
    孤寂的欢愉
    论神性与人性
    使用NPOI读取Excel出错
  • 原文地址:https://www.cnblogs.com/wolf940509/p/5484963.html
Copyright © 2011-2022 走看看