原来我可以这么的暴力,,,树,并查集,深搜~

1、http://acm.hdu.edu.cn/showproblem.php?pid=1198

 

 

解题思路:用深搜来标记从可行的一个位置出发所能达到的所有的点,组成一个连通的图块,求和~

 

#include<stdio.h> #include<memory.h> #define M 55 int dir[][2]={{0,1},{1,0},{0,-1},{-1,0}}; char judge[11][11][5]= {//暴力倾注的查询表,不要问我为什么,不能解释... "0000","0010","0001","0011","0001","0010","0010","0001","0011","0011","0011", "1000","0000","1001","0001","0001","1000","1000","1001","1001","0001","1001", "0100","0110","0000","0010","0100","0010","0110","0100","0010","0110","0110", "1100","0100","1000","0000","0100","1000","1100","1100","1000","0100","1100", "0100","0100","0001","0001","0101","0000","0100","0101","0001","0101","0101", "1000","0010","1000","0010","0000","1010","1010","1000","1010","0010","1010", "1000","0010","1001","0011","0001","1010","1010","1001","1011","0011","1011", "0100","0110","0001","0011","0101","0010","0110","0101","0011","0111","0111", "1100","0110","1000","0010","0100","1010","1110","1100","1010","0110","1110", "1100","0100","1001","0001","0101","1000","1100","1101","1001","0101","1101", "1100","0110","1001","0011","0101","1010","1110","1101","1011","0111","1111" }; char map[M][M]; int mark[M][M]; int r,c,count; void dfs(int x,int y) { int a,b,i; mark[x][y]=1; for(i=0;i<4;i++){ a=x+dir[i][0]; b=y+dir[i][1]; if(!mark[a][b]&&a>=0&&a<r&&b>=0&&b<c &&(judge[map[x][y]-'A'][map[a][b]-'A'][i]=='1')) dfs(a,b); } } void run() { int i,j; for(i=0;i<r;i++){ for(j=0;j<c;j++) if(!mark[i][j]){ dfs(i,j); count++; } } return ; } int main() { int i; while(scanf("%d%d",&r,&c),r!=-1&&c!=-1){ for(i=0;i<r;i++) scanf("%s",map[i]); memset(mark,0,sizeof(mark)); count=0; run(); printf("%d/n",count); } return 0; }

 

 

2、http://acm.hdu.edu.cn/showproblem.php?pid=1232

 

畅通工程,

 

解题思路:用并查集找出各连通分量,所需的最小路数即为其值减一;

 

 

/*使用并查集找出全部连通分量,即所生成的树个数*/ #include<stdio.h> #include<memory.h> #define M 1001 int father[M]; int n,m; void init() {//初始化 int i; for(i=1;i<=n;i++) father[i]=i; } int root(int r) {//查找元素r的根结点,压缩路径, if(!father[r]) return father[r]=r; if(r!=father[r]) father[r]=root(father[r]); return father[r]; } void merge(int x,int y) {//合并两集合 int a,b; a=root(x); b=root(y); if(a!=b) father[b]=a; } int main() { int i,a,b,sum; while(scanf("%d",&n),n){ scanf("%d",&m); sum=0;init(); while(m--){ scanf("%d%d",&a,&b); father[a]=root(a); father[b]=root(b); merge(a,b); } for(i=1;i<=n;i++){//如果father[i]==i,则i为集合形成树的根结点 if(father[i]==i) sum++; } printf("%d/n",sum-1); } return 0; }

你可能感兴趣的:(原来我可以这么的暴力,,,树,并查集,深搜~)