HDU 3371 Connect the Cities(Prim,Kruskal)
来源:互联网 发布:淘宝账号严重违规冻结 编辑:程序博客网 时间:2024/06/05 15:49
题目地址:点击打开链接
题意:给你一堆城市,然后来了一次海啸,海啸完了还有一些城市是连在一块的,问把所有的城市连在最小的花费是多少
思路:Kruskal算法超了无数发,后来改用prim算法,把海啸过后,连在一块的城市之间的距离设为0即可,用C++提交
AC代码:
#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <queue>#include <stack>#include <map>#include <cstring>#include <climits>#include <cmath>#include <cctype>using namespace std;const int maxn = 510;const int zui = 0x3f3f3f3f;int lowdist[maxn];int map1[maxn][maxn];int visit[maxn];int n,m,k,sum;bool flag;void Prim(){ int i,j,k; memset(visit,0,sizeof(visit)); for(i=1; i<=n; i++) { lowdist[i] = map1[1][i]; } visit[1] = 1; sum = 0; for(i=1; i<n; i++) { int min1 = zui; for(j=1; j<=n; j++) { if(!visit[j] && lowdist[j] < min1) { min1 = lowdist[j]; k = j; } } if(min1 == zui) { flag = false; return; } visit[k] = 1; sum += lowdist[k]; for(j=1; j<=n; j++) { if(!visit[j] && map1[k][j] < lowdist[j]) { lowdist[j] = map1[k][j]; } } }}int main(){ int t; int i,j; scanf("%d",&t); while(t--) { flag = true; memset(map1,zui,sizeof(map1)); scanf("%d%d%d",&n,&m,&k); int p,q,c; for(i=1; i<=m; i++) { scanf("%d%d%d",&p,&q,&c); if(c < map1[p][q]) { map1[p][q] = map1[q][p] = c; } } int l,temp,x; for(i=1; i<=k; i++) { scanf("%d%d",&l,&temp); for(j=1; j<l; j++) { scanf("%d",&x); map1[temp][x] = map1[x][temp] = 0; } } Prim(); if(flag) { printf("%d\n",sum); } else { printf("-1\n"); } } return 0;}
AC代码2:该开始用G++投的T了,和代码1没啥区别就是初始化是用了循环语句,后来代码1用从C++过了,然后把这个代码也试着用C++投,也过了,不过时间比代码1长一点
#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <queue>#include <stack>#include <map>#include <cstring>#include <climits>#include <cmath>#include <cctype>using namespace std;const int maxn = 510;const int zui = 1000000000;int lowdist[maxn];int map1[maxn][maxn];int visit[maxn];int n,m,k,sum;bool flag;void Prim(){ int i,j,k; memset(visit,0,sizeof(visit)); for(i=1; i<=n; i++) { lowdist[i] = map1[1][i]; } visit[1] = 1; sum = 0; for(i=1; i<n; i++) { int min1 = zui; for(j=1; j<=n; j++) { if(!visit[j] && lowdist[j] < min1) { min1 = lowdist[j]; k = j; } } if(min1 == zui) { flag = false; return; } visit[k] = 1; sum += lowdist[k]; for(j=1; j<=n; j++) { if(!visit[j] && map1[k][j] < lowdist[j]) { lowdist[j] = map1[k][j]; } } }}int main(){ int t; int i,j; scanf("%d",&t); while(t--) { flag = true; scanf("%d%d%d",&n,&m,&k); for(i=1; i<=n; i++) { for(j=1; j<=n; j++) { map1[i][j] = zui; } map1[i][i] = 0; } int p,q,c; for(i=1; i<=m; i++) { scanf("%d%d%d",&p,&q,&c); if(c < map1[p][q]) { map1[p][q] = map1[q][p] = c; } } int l,temp,x; for(i=1; i<=k; i++) { scanf("%d%d",&l,&temp); for(j=1; j<l; j++) { scanf("%d",&x); map1[temp][x] = map1[x][temp] = 0; } } Prim(); if(flag) { printf("%d\n",sum); } else { printf("-1\n"); } } return 0;}最后来点Kruskal的超时代码
超时代码1:
#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <queue>#include <stack>#include <map>#include <cstring>#include <climits>#include <cmath>#include <cctype>using namespace std;const int maxn = 510;const int zui = 1000000000;int lowdist[maxn];int map1[maxn][maxn];int visit[maxn];int n,m,k,sum;bool flag;void Prim(){ int i,j,k; memset(visit,0,sizeof(visit)); for(i=1; i<=n; i++) { lowdist[i] = map1[1][i]; } visit[1] = 1; sum = 0; for(i=1; i<n; i++) { int min1 = zui; for(j=1; j<=n; j++) { if(!visit[j] && lowdist[j] < min1) { min1 = lowdist[j]; k = j; } } if(min1 == zui) { flag = false; return; } visit[k] = 1; sum += lowdist[k]; for(j=1; j<=n; j++) { if(!visit[j] && map1[k][j] < lowdist[j]) { lowdist[j] = map1[k][j]; } } }}int main(){ int t; int i,j; scanf("%d",&t); while(t--) { flag = true; scanf("%d%d%d",&n,&m,&k); for(i=1; i<=n; i++) { for(j=1; j<=n; j++) { map1[i][j] = zui; } map1[i][i] = 0; } int p,q,c; for(i=1; i<=m; i++) { scanf("%d%d%d",&p,&q,&c); if(c < map1[p][q]) { map1[p][q] = map1[q][p] = c; } } int l,temp,x; for(i=1; i<=k; i++) { scanf("%d%d",&l,&temp); for(j=1; j<l; j++) { scanf("%d",&x); map1[temp][x] = map1[x][temp] = 0; } } Prim(); if(flag) { printf("%d\n",sum); } else { printf("-1\n"); } } return 0;}
用k判环超时,改用n判环,里面少一个for循环,时间应该少很多
超时代码2:
#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <queue>#include <stack>#include <map>#include <cstring>#include <climits>#include <cmath>#include <cctype>using namespace std;int pre[510];struct node{ int left,right,value;}a[25010];int cmp(const void *_a,const void *_b){ struct node *a = (node*)_a; struct node *b = (node*)_b; return a->value - b->value;}int findroot(int x){ return x == pre[x] ? x : pre[x] = findroot(pre[x]);//求根节点加路径压缩}int main(){ int t,n,m,k; int i,j; scanf("%d",&t); while(t--) { scanf("%d%d%d",&n,&m,&k); for(i=1; i<=n; i++) { pre[i] = i; } for(i=0; i<m; i++) { scanf("%d%d%d",&a[i].left,&a[i].right,&a[i].value); } qsort(a,m,sizeof(node),cmp); int sum,l,x; int root1,root2; for(i=0; i<k; i++) { scanf("%d",&sum); scanf("%d",&l); root1 = findroot(l); for(j=1; j<sum; j++) { scanf("%d",&x); root2 = findroot(x); if(root1 != root2) { pre[root2] = pre[root1]; n--; } } } sum = 0; for(i=0; i<m; i++) { root1 = findroot(a[i].left); root2 = findroot(a[i].right); if(root1 != root2) { sum += a[i].value; pre[root1] = root2; n--; } if(n == 1) break; } if(n == 1) { printf("%d\n",sum); } else { printf("-1\n"); } } return 0;}用n判环依旧超
超时代码3:
#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <queue>#include <stack>#include <map>#include <cstring>#include <climits>#include <cmath>#include <cctype>using namespace std;int pre[510];struct node{ int left,right,value;}a[25010];int cmp(const void *_a,const void *_b){ struct node *a = (node*)_a; struct node *b = (node*)_b; return a->value - b->value;}int findroot(int x){ return x == pre[x] ? x : pre[x] = findroot(pre[x]);//求根节点加路径压缩}int main(){ int t,n,m,k; int i,j; scanf("%d",&t); while(t--) { scanf("%d%d%d",&n,&m,&k); for(i=1; i<=n; i++) { pre[i] = i; } for(i=0; i<m; i++) { scanf("%d%d%d",&a[i].left,&a[i].right,&a[i].value); } qsort(a,m,sizeof(node),cmp); int sum,l,x; int root1,root2; for(i=0; i<k; i++) { scanf("%d",&sum); scanf("%d",&l); root1 = findroot(l); for(j=1; j<sum; j++) { scanf("%d",&x); root2 = findroot(x); if(root1 != root2) { pre[root2] = pre[root1]; n--; } } } sum = 0; for(i=0; i<m; i++) { if(pre[a[i].left] != pre[a[i].right]) { pre[pre[a[i].left]] = pre[a[i].right]; sum += a[i].value; n--; } if(n == 1) break; } if(n == 1) { printf("%d\n",sum); } else { printf("-1\n"); } } return 0;}减少函数调用依旧超时
0 0
- hdu 3371 Connect the Cities【kruskal&prim】
- HDU 3371 Connect the Cities(Prim,Kruskal)
- hdu 3371 Connect the cities (prim)
- HDU 3371 Connect the Cities 【kruskal】
- hdu 3371 Connect the Cities(prim)
- hdu 3371 Connect the Cities <prim>
- hdu 3371 Connect the Cities (Prim)
- hdu 3371 Connect the Cities,(kruskal算法)
- hdu 3371 Connect the Cities Prim + Kruskal两种算法分别AC 水过~~~~
- hdu 3371 Connect the Cities(prim算法)
- hdu 3371 Connect the Cities 最小生成树(kruskal算法)
- hdu 3371 Connect the Cities (Kruskal+ 并查集)
- hdu 3371 Connect the Cities(最小生成树kruskal)
- hdu 3371 Connect the Cities 最小生成树prim
- Connect the Cities(Prim)
- 文章标题 HDU 3371 : Connect the Cities(最小生成树--Kruskal+并查集)
- hdu 3371 Connect the Cities (prime)
- hdoj3371-Connect the Cities(prim)
- TNS:无监听程序”问题的解决
- (13)字符串查找
- Xcode修改字体设置
- spring2.5 jar包介绍
- pyqt基础教程(一)
- HDU 3371 Connect the Cities(Prim,Kruskal)
- 连续邮资问题
- 【旅行】北京之行 to My First Trip
- 你不知道的JavaScript--Item11 arguments对象
- 直布购物助手怎么使用
- 各种编码
- Linux vi命令用法
- 原码,补码,反码的由来与转换
- MySql连接及数据的传输例子