从零单排11

来源:互联网 发布:绿艺园艺三角梅淘宝店 编辑:程序博客网 时间:2024/04/29 23:06

晚上学习了最小生成树。。就是Prim算法。。

关于Kruskal算法准备学到并查集的时候再去解决它

网上搜到好多题解不太满意。。

花了一个多小时东拼西凑了一份模版。。

悲剧。。

一晚上的最小生成树水题

就是套模版。。


以下题解:

hdu 1879:http://acm.hdu.edu.cn/showproblem.php?pid=1879

/*最小生成树裸题 我草。。。输入没判断n!=0导致wa了一万遍 。。。*/#include<iostream>#include <algorithm>using namespace std ;#define INF0x3f3f3f3f#define MAXN 105#define MAXE (MAXN*MAXN)int n,m;int used[MAXN],dist[MAXN];int map[MAXN][MAXN];int Prim(){int i,j,iMinPath,MinPath,sum;memset(used,0,sizeof(used));for(i=1;i<=n;++i)dist[i]=map[1][i] ;used[1]=true;sum=0;for(i=1;i<=n-1;i++)//最小生成树需要n-1条边 {MinPath=INF;for(j=1;j<=n;j++){ if(!used[j]&&dist[j]<MinPath){MinPath=dist[j] ;iMinPath=j;}}used[iMinPath]=true;sum+=MinPath;for(j=1;j<=n;j++){if(!used[j]&&dist[j]>map[iMinPath][j])dist[j]=map[iMinPath][j] ;}}return sum ;}void getmap(){for(int i=1;i<=m;i++){int x,y,l,flag;cin>>x>>y>>l>>flag; if(flag)l=0;map[x][y]=map[y][x]=min(map[x][y],l) ;}}int main (){int i;while(cin>>n&&n!=0){memset(map,INF,sizeof(map));m=n*(n-1)/2;getmap();cout<<Prim()<<endl;}return 0 ;}
hdu 1102:http://acm.hdu.edu.cn/showproblem.php?pid=1102

/*最小生成树裸题。。套模版*/#include<iostream>#define INF0x3f3f3f3f#define MAXN 105#define MAXE (MAXN*MAXN)using namespace std;int n,m;int used[MAXN],dist[MAXN];int map[MAXN][MAXN];void getmap(){for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){cin>>map[i][j];}}}int Prim(){int i,j,iMinPath,MinPath,sum;memset(used,0,sizeof(used));for(i=1;i<=n;++i)dist[i]=map[1][i] ;used[1]=true;sum=0;for(i=1;i<=n-1;i++)//最小生成树需要n-1条边 {MinPath=INF;for(j=1;j<=n;j++){ if(!used[j]&&dist[j]<MinPath){MinPath=dist[j] ;iMinPath=j;}}used[iMinPath]=true;sum+=MinPath;for(j=1;j<=n;j++){if(!used[j]&&dist[j]>map[iMinPath][j])dist[j]=map[iMinPath][j] ;}}return sum ;}int main(){while(cin>>n){memset(map,INF,sizeof(map));getmap();int q;cin>>q;while(q--){int x,y;cin>>x>>y;map[x][y]=map[y][x]=0;}cout<<Prim()<<endl;}system("pause");return 0;}

hdu 3371:http://acm.hdu.edu.cn/showproblem.php?pid=3371

/*裸最小生成树 用cin导致超时了*/#include<iostream>using namespace std;#define INF0x3f3f3f3f#define MAXN 505#define MAXE (MAXN*MAXN)int n,m,k;int used[MAXN],dist[MAXN];int map[MAXN][MAXN];void Prim(){int i,j,iMinPath,MinPath,sum;memset(used,0,sizeof(used));for(i=1;i<=n;++i)dist[i]=map[1][i] ;used[1]=true;sum=0;for(i=1;i<=n-1;i++)//最小生成树需要n-1条边 {MinPath=INF;for(j=1;j<=n;j++){ if(!used[j]&&dist[j]<MinPath){MinPath=dist[j] ;iMinPath=j;}}if(MinPath==INF)break;used[iMinPath]=true;sum+=MinPath;for(j=1;j<=n;j++){if(!used[j]&&dist[j]>map[iMinPath][j])dist[j]=map[iMinPath][j] ;}}if(MinPath==INF){printf("-1\n");}else{printf("%d\n",sum);}}void getmap(){for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){map[i][j]=INF;}} for(int i=1;i<=m;i++){int x,y,l;scanf("%d%d%d",&x,&y,&l);map[x][y]=map[y][x]=min(map[x][y],l) ;}}int main(){int T;scanf("%d",&T);while(T--){scanf("%d%d%d",&n,&m,&k);getmap();while(k--){int t,i;scanf("%d%d",&t,&i);while(--t){int j;scanf("%d",&j);map[i][j]=map[j][i]=0;i=j;}}Prim();}system("pause");return 0;}

hdu 1863:http://acm.hdu.edu.cn/showproblem.php?pid=1863

/*最小生成树裸题 注意m和n的意义其他就是套模版了*/#include<iostream>using namespace std;#define INF0x3f3f3f3f#define MAXN 505#define MAXE (MAXN*MAXN)int n,m,k;int used[MAXN],dist[MAXN];int map[MAXN][MAXN];void Prim(){int i,j,iMinPath,MinPath,sum;memset(used,0,sizeof(used));for(i=1;i<=n;++i)dist[i]=map[1][i] ;used[1]=true;sum=0;for(i=1;i<=n-1;i++)//最小生成树需要n-1条边 {MinPath=INF;for(j=1;j<=n;j++){ if(!used[j]&&dist[j]<MinPath){MinPath=dist[j] ;iMinPath=j;}}if(MinPath==INF)break;used[iMinPath]=true;sum+=MinPath;for(j=1;j<=n;j++){if(!used[j]&&dist[j]>map[iMinPath][j])dist[j]=map[iMinPath][j] ;}}if(MinPath==INF){printf("?\n");}else{printf("%d\n",sum);}}void getmap(){for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){map[i][j]=INF;}} for(int i=1;i<=m;i++){int x,y,l;scanf("%d%d%d",&x,&y,&l);map[x][y]=map[y][x]=min(map[x][y],l) ;}}int main(){while(cin>>m>>n,m!=0){getmap();Prim();}system("pause");return 0;}

hdu 1301:http://acm.hdu.edu.cn/showproblem.php?pid=1301

/*Kruskal算法网上搜的题解不太满意 以后学习到并查集的时候再来看这个算法*/ #include <cstdio>#include <cstdlib>#include <iostream>using namespace std;const int M = 700;int p[27], sum;struct edge {    int a;    int b;    int w;}e[M];int cmp(const void *a, const void *b) {    return (*(edge *)a).w - (*(edge *)b).w;}void init(int vs) {    for (int i=1; i<=vs; ++i) p[i] = i;    return ;}int find(int v) {    if (p[v] != v) p[v] = find(p[v]);    return p[v];}int join(edge e) {    int x, y;    x = find(e.a);    y = find(e.b);    if (x != y) {        ++sum;        p[x] = y;        return e.w;    }    return 0;}int kruskal(int es, int vs) {    int ans = 0;    init(vs);    qsort(e, es, sizeof(edge), cmp);    for (int i=0; i<es; ++i) {        ans += join(e[i]);        if (sum == vs) return ans;    }}int main() {    int n;    while (cin>>n) {        if (n == 0) break;        char c;        int k, w, es;        es = 0;        for (int i=1; i<n; ++i) {            cin>>c>>k;            for (int j=0; j<k; ++j) {                cin>>c>>w;                e[es].w = w;                e[es].a = i;                e[es].b = c - 'A' + 1;                ++es;            }        }        sum = 1;        int ans = kruskal(es, n);        printf ("%d\n", ans);    }    return 0;}


这样大一下的任务差不多算完成了。。。

矩阵那部分准备以后再看》。。

线性代数学了和没学一样。。。

然后接下来的一段时间要准备一下下个周的unix考试和物理实验神马的。。

o(︶︿︶)o 唉

题目再做一些零零散散的吧...

加油屎宝宝~!


原创粉丝点击