pku 1235 Galactic Breakup 并查集

题意:
一个帝国有N个国家组成,每个国家包括Ni个区域(一个小方格),然后第i个国家在第i月会分离出去。问有多少个月帝国仍然是一个整体。
PS:说道帝国,就想到黄金雄教授在ICPC开幕式上用闽南语讲的(。。。ACM大帝国。。),那发音,拿语言的组织都超级搞笑


思路:
并查集,逆向思维。最后所有的国家应该都是独立的。相当于一个国家一个国家逐月的联合起来。用并查集统计是否当前集合为一个整体即可。暴力的方法没实验过,不过复杂度会高达30^6,(*^__^*) 嘻嘻……,RP好的可以去拼一下~

代码:
 1 //============================================================================
 2 // Name        : pku1235.cpp
 3 // Author      : yzhw
 4 // Version     :
 5 // Copyright   : yzhw
 6 // Description : Hello World in C++, Ansi-style
 7 //============================================================================
 8 
 9 #include <iostream>
10 #include <cstdio>
11 #include <vector>
12 #include <algorithm>
13 using namespace std;
14 # define LEFT (data[i][j]%(n*m))
15 int set[30000],n,m,k,l,data[30000][21];
16 bool used[30000];
17 int find(int pos)
18 {
19     if(set[pos]==pos) return pos;
20     else return set[pos]=find(set[pos]);
21 }
22 int main() {
23     int testcase;
24     scanf("%d",&testcase);
25     while(testcase--)
26     {
27         scanf("%d%d%d%d",&n,&m,&k,&l);
28         int total=0,ans=0,c;
29         for(int i=0;i<n*m*k;i++)
30             set[i]=i,used[i]=false;
31         for(int i=0;i<l;i++)
32         {
33             scanf("%d",&data[i][0]);
34             for(int j=1;j<=data[i][0];j++)
35                 scanf("%d",&data[i][j]);
36         }
37         for(int i=l-1;i>=0;i--)
38         {
39             c=0;
40             for(int j=1;j<=data[i][0];j++)
41             {
42                 vector<int> refer;
43                 if(data[i][j]-n*m>=0&&used[data[i][j]-n*m]) refer.push_back(find(data[i][j]-n*m));
44                 if(data[i][j]+n*m<n*m*k&&used[data[i][j]+n*m]) refer.push_back(find(data[i][j]+n*m));
45                 if(LEFT%n!=0&&used[data[i][j]-1]) refer.push_back(find(data[i][j]-1));
46                 if(LEFT%n!=n-1&&used[data[i][j]+1]) refer.push_back(find(data[i][j]+1));
47                 if(LEFT/n!=0&&used[data[i][j]-n]) refer.push_back(find(data[i][j]-n));
48                 if(LEFT/n!=m-1&&used[data[i][j]+n]) refer.push_back(find(data[i][j]+n));
49                 sort(refer.begin(),refer.end());
50                 vector<int>::iterator end=unique(refer.begin(),refer.end());
51                 c+=end-refer.begin();
52                 for(int t=0;t<end-refer.begin();t++)
53                     set[find(refer[t])]=find(data[i][j]);
54                 used[data[i][j]]=true;
55             }
56             total=total+data[i][0]-c;
57             if(total==1) ans++;
58         }
59         printf("%d\n",l-ans);
60     }
61     return 0;
62 }

posted on 2011-01-20 20:44 yzhw 阅读(121) 评论(0)  编辑 收藏 引用 所属分类: data struct


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2010年11月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

导航

统计

公告

统计系统

留言簿(1)

随笔分类(227)

文章分类(2)

OJ

最新随笔

搜索

积分与排名

最新评论

阅读排行榜