A & M - Jungle Roads HDU - 1301

题意:字母之间的路,求最小生成树

题解:处理好建边以后就是一个Prime

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<sstream>
#include<cmath>
#include<stack>
#include<cstdlib>
#include <vector>
#include <set>
#include<queue>
#include<map>
using namespace std; #define ll long long
#define llu unsigned long long
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
const int maxn = ;
const ll mod = 1e9+;
const double eps = 1e-; bool vis[maxn];
int lowc[maxn]; int Prim(int cost[][maxn],int n)
{
int ans = ;
memset(vis,false,sizeof vis);
vis[] = true;
for(int i=;i<n;i++)
lowc[i] = cost[][i];
for(int i=;i<n;i++)
{
int minc = INF;
int p = -;
for(int j=;j<n;j++)
{
if(!vis[j] && minc > lowc[j])
{
minc = lowc[j];
p = j;
}
}
if(minc == INF)
return -;
ans += minc;
vis[p] = true;
for(int j=;j<n;j++)
if(!vis[j] && lowc[j] > cost[p][j])
lowc[j] = cost[p][j];
}
return ans;
}
int main()
{
int n;
while(scanf("%d",&n) && n)
{
int cost[maxn][maxn];
for(int i=;i<maxn;i++)
{
for(int j=;j<maxn;j++)
if(i == j)
cost[i][j] = ;
else
cost[i][j] = INF;
}
for(int i=;i<n;i++)
{
char a;
cin>>a;
int num;
cin>>num;
for(int i=;i<num;i++)
{
char ch;
int len;
cin>>ch>>len;
cost[a-'A'][ch-'A'] = len;
cost[ch-'A'][a-'A'] = len;
}
} int ans = Prim(cost,n);
cout<<ans<<endl;
} }

B - Networking POJ - 1287

题意:有重复边的跑最小生成树

题解:边取小跑Prime

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<sstream>
#include<cmath>
#include<stack>
#include<cstdlib>
#include <vector>
#include <set>
#include<queue> using namespace std; #define ll long long
#define llu unsigned long long
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
const int maxn = 1e2+;
bool vis[maxn];
int lowc[maxn];
int Prim(int cost[][maxn],int n)
{
int ans = ;
memset(vis,false,sizeof vis);
vis[] = true;
for(int i=;i<=n;i++)
lowc[i] = cost[][i];
for(int i=;i<=n;i++)
{
int minc = INF;
int p = -;
for(int j=;j<=n;j++)
if(!vis[j] && minc > lowc[j])
{
minc = lowc[j];
p = j;
}
if(minc == INF)
return -;
ans += minc;
vis[p] = true;
for(int j=;j<=n;j++)
if(!vis[j] && lowc[j] > cost[p][j])
lowc[j] = cost[p][j];
}
return ans; }
int main()
{
int n,m;
while(scanf("%d",&n) && n)
{
scanf("%d",&m);
int cost[maxn][maxn];
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
if(i == j)
cost[i][j] = ;
else
cost[i][j] = INF;
for(int i=;i<m;i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
cost[a][b] = min(cost[a][b],c);
cost[b][a] = min(cost[b][a],c);
cost[a][b] = cost[b][a] = min(cost[a][b],cost[b][a]);
}
int ans = Prim(cost,n);
printf("%d\n",ans);
}
}

C - Building a Space Station POJ - 2031

题意:三维上的球上建最小生成树

题解:处理边即可

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<sstream>
#include<cmath>
#include<stack>
#include<cstdlib>
#include <vector>
#include <set>
#include<queue> using namespace std; #define ll long long
#define llu unsigned long long
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
const int maxn = 1e2+; struct node
{
double x,y,z,r;
}a[maxn];
double dis(double x1,double y1,double z1,double r1,double x2,double y2,double z2,double r2)
{
double len = (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) + (z1-z2)*(z1-z2);
double ans = sqrt(len) - r1 - r2;
return max(0.0,ans);
}
bool vis[maxn];
double lowc[maxn];
double Prime(double cost[][maxn],int n)
{
double ans = ;
memset(vis,,sizeof vis);
vis[] = true;
for(int i=;i<n;i++)
lowc[i] = cost[][i];
for(int i=;i<n;i++)
{
double minc = 9999999999.9;
int p = -;
for(int j=;j<n;j++)
if(!vis[j] && minc > lowc[j])
{
p = j;
minc = lowc[j];
}
ans += minc;
vis[p] = true;
for(int j=;j<n;j++)
if(!vis[j] && lowc[j] > cost[p][j])
lowc[j] = cost[p][j];
}
return ans;
}
int main()
{
int n;
while(scanf("%d",&n) && n)
{
double cost[maxn][maxn];
for(int i=;i<n;i++)
scanf("%lf %lf %lf %lf",&a[i].x,&a[i].y,&a[i].z,&a[i].r);
for(int i=;i<n;i++)
for(int j=;j<n;j++)
cost[i][j] = dis(a[i].x,a[i].y,a[i].z,a[i].r,a[j].x,a[j].y,a[j].z,a[j].r);
double ans = Prime(cost,n);
printf("%.3f\n",ans);
}
}

D - Constructing Roads POJ - 2421

题意:邻接矩阵有些边权值为0,求最小生成树

题解:Prim

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<sstream>
#include<cmath>
#include<stack>
#include<cstdlib>
#include <vector>
#include <set>
#include<queue> using namespace std; #define ll long long
#define llu unsigned long long
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
const int maxn = 1e2+; int vis[maxn];
int lowc[maxn];
int cost[maxn][maxn]; int Prim(int cost[][maxn],int n)
{
int ans = ;
memset(vis,,sizeof vis);
vis[] = true;
for(int i=;i<=n;i++)
lowc[i] = cost[][i];
for(int i=;i<=n;i++)
{
int minc = INF;
int p = -;
for(int j=;j<=n;j++)
if(!vis[j] && minc > lowc[j])
{
minc = lowc[j];
p = j;
}
ans += minc;
vis[p] = true;
for(int j=;j<=n;j++)
if(!vis[j] && lowc[j] > cost[p][j])
lowc[j] = cost[p][j];
}
return ans;
}
int main()
{
int n;
scanf("%d",&n);
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
scanf("%d",&cost[i][j]);
int q;
scanf("%d",&q);
for(int i=;i<q;i++)
{
int a,b;
scanf("%d%d",&a,&b);
cost[a][b] = cost[b][a] = ;
}
int ans = Prim(cost,n);
printf("%d\n",ans);
}

E - QS Network ZOJ - 1586

题意:最小生出树,边的值还需要加上两个顶点的值

题解:只需要将顶点的值加到其权值上即可

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<sstream>
#include<cmath>
#include<stack>
#include<cstdlib>
#include <vector>
#include <set>
#include<queue> using namespace std; #define ll long long
#define llu unsigned long long
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
const int maxn = 1e3+; bool vis[maxn];
int lowc[maxn];
int cost[maxn][maxn];
int a[maxn];
int prim(int cost[][maxn],int n)
{
int ans = ;
memset(vis,false,sizeof vis);
vis[] = true;
for(int i=;i<=n;i++)
lowc[i] = cost[][i];
for(int i=;i<=n;i++)
{
int minc = INF;
int p = -;
for(int j=;j<=n;j++)
{
if(!vis[j] && minc > lowc[j])
{
minc = lowc[j];
p = j;
}
}
ans += minc;
vis[p] = true;
for(int j=;j<=n;j++)
if(!vis[j] && lowc[j] > cost[p][j])
lowc[j] = cost[p][j];
}
return ans;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
int ans = ;
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%d",&a[i]);
for(int i=;i<=n;i++)
for(int j=;j<=n;j++) {
scanf("%d", &cost[i][j]);
cost[i][j] += a[i] + a[j];
}
ans += prim(cost,n);
printf("%d\n",ans);
}
}

F - Truck History POJ - 1789

题意:两个字符串之间不同的个数为边的权值,跑最小生成树

题解:处理边之后跑最小生成树

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<sstream>
#include<cmath>
#include<stack>
#include<cstdlib>
#include <vector>
#include <set>
#include<queue> using namespace std; #define ll long long
#define llu unsigned long long
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
const int maxn = 2e3+; bool vis[maxn];
int lowc[maxn];
int cost[maxn][maxn];
int a[maxn];
int prim(int cost[][maxn],int n)
{
int ans = ;
memset(vis,false,sizeof vis);
vis[] = true;
for(int i=;i<=n;i++)
lowc[i] = cost[][i];
for(int i=;i<=n;i++)
{
int minc = INF;
int p = -;
for(int j=;j<=n;j++)
{
if(!vis[j] && minc > lowc[j])
{
minc = lowc[j];
p = j;
}
}
ans += minc;
vis[p] = true;
for(int j=;j<=n;j++)
if(!vis[j] && lowc[j] > cost[p][j])
lowc[j] = cost[p][j];
}
return ans;
}
int main()
{
int n;
while(scanf("%d",&n) && n)
{
char str[maxn][];
for(int i=;i<=n;i++)
scanf("%s",str[i]);
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
{
int tmp = ;
for(int k=;k<;k++)
if(str[i][k] != str[j][k])
tmp++;
cost[i][j] = cost[j][i] = tmp;
}
int ans = prim(cost,n);
printf("The highest possible quality is 1/%d.\n",ans);
}
}

J - Borg Maze POJ - 3026

题意:迷宫之中的MST

题解:先bfs预处理,之后在进行MST,输入的时候有坑点,wa了好几次

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<sstream>
#include<cmath>
#include<stack>
#include<cstdlib>
#include <vector>
#include <set>
#include<queue> using namespace std; #define ll long long
#define llu unsigned long long
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
const int maxn = ;
int tree[maxn][maxn],id[maxn][maxn],dis[maxn][maxn],n,m,tot;
bool vis[maxn][maxn];
int lowc[maxn],visit[maxn];
char mp[maxn][maxn];
int dx[] = {,,,-};
int dy[] = {,,-,};
struct node
{
int x,y;
};
bool check(int x,int y)
{
if(x >= && x <= n && y >= && y <= m && !vis[x][y] && mp[x][y] != '#')
return true;
return false;
}
void bfs(int x,int y)
{
memset(vis,false,sizeof vis);
memset(dis,,sizeof dis);
queue<node>que;
node temp;
temp.x = x;
temp.y = y;
que.push(temp);
vis[x][y] = true;
while(!que.empty())
{
temp = que.front();
que.pop();
for(int i=;i<;i++)
{
int nx = temp.x + dx[i];
int ny = temp.y + dy[i];
if(check(nx,ny))
{
vis[nx][ny] = true;
dis[nx][ny] = dis[temp.x][temp.y] + ;
if(mp[nx][ny] == 'A' || mp[nx][ny] == 'S')
tree[id[x][y]][id[nx][ny]] = tree[id[nx][ny]][id[x][y]] = dis[nx][ny];
que.push(node{nx,ny});
}
}
}
} int Prime(int cost[][maxn],int n)
{
int ans = ;
memset(visit,false,sizeof visit);
visit[] = true;
for(int i=;i<=n;i++)
lowc[i] = cost[][i];
for(int i=;i<=n;i++)
{
int minc = INF;
int p = -;
for(int j=;j<=n;j++)
if(!visit[j] && minc > lowc[j])
{
minc = lowc[j];
p = j;
}
ans += minc;
visit[p] = true;
for(int j=;j<=n;j++)
if(!visit[j] && lowc[j] > cost[p][j])
lowc[j] = cost[p][j];
}
return ans;
} int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int tot = ;
scanf("%d%d ",&m,&n);
for(int i=;i<=n;i++)
gets(mp[i] + );
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
if(mp[i][j] == 'A' || mp[i][j] == 'S')
id[i][j] = ++tot;
for(int i=;i<=tot;i++)
for(int j=;j<=tot;j++)
if(i == j)
tree[i][j] = ;
else
tree[i][j] = INF;
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
if(mp[i][j] == 'A' || mp[i][j] == 'S')
bfs(i,j);
int ans = Prime(tree,tot);
printf("%d\n",ans);
}
}

L - 还是畅通工程 HDU - 1233

题意:直接就是求最小生成树了

题解:板子

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<sstream>
#include<cmath>
#include<stack>
#include<cstdlib>
#include <vector>
#include <set>
#include<queue>
#include<map>
using namespace std; #define ll long long
#define llu unsigned long long
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
const int maxn = ;
const ll mod = 1e9+;
const double eps = 1e-; int lowc[maxn];
bool vis[maxn]; int Prime(int cost[][maxn],int n)
{
int ans = ;
memset(vis,false,sizeof vis);
vis[] = true;
for(int i=;i<n;i++)
lowc[i] = cost[][i];
for(int i=;i<n;i++)
{
int minc = INF;
int p = -;
for(int j=;j<n;j++)
{
if(!vis[j] && minc > lowc[j])
{
minc = lowc[j];
p = j;
}
}
if(minc == INF)
return -;
ans += minc;
vis[p] = true;
for(int j=;j<n;j++)
if(!vis[j] && lowc[j] > cost[p][j])
lowc[j] = cost[p][j];
}
return ans;
}
int main()
{
int n;
while(scanf("%d",&n) && n)
{
int cost[maxn][maxn];
memset(cost,,sizeof cost);
for (int i = ; i < n * (n - ) / ; i++)
{
int a, b, l;
scanf("%d%d%d", &a, &b, &l);
cost[a-][b-] = l;
cost[b-][a-] = l;
} int ans = Prime(cost, n);
printf("%d\n", ans);
}
}

N - 畅通工程再续 HDU - 1875

题意:岛之间造桥,只有长度在10~1000才可以造,问最少的花费,花费是桥的长度*100

题解:INF值的判定,INF是长度小于10或者长度大于1000,其余就是Prime的板子

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<sstream>
#include<cmath>
#include<stack>
#include<cstdlib>
#include <vector>
#include <set>
#include<queue>
#include<map>
using namespace std; #define ll long long
#define llu unsigned long long
#define INF 99999999999.9
#define PI acos(-1.0)
const int maxn = ;
const ll mod = 1e9+;
const double eps = 1e-; double lowc[maxn];
bool vis[maxn];
double dis(int x1,int y1,int x2,int y2)
{
double ans = sqrt((double)(x2-x1)*(x2-x1)*1.0 + (y2-y1)*(y2-y1)*1.0);
//cout<<ans<<endl;
return ans;
}
bool check(double x)
{
//cout<<x<<endl;
if(x>=10.0 && x<=1000.0)
return true;
else
return false;
}
double Prime(double cost[][maxn],int n)
{
double ans = ;
memset(vis,false,sizeof vis);
vis[] = true;
for(int i=;i<n;i++)
lowc[i] = cost[][i];
for(int i=;i<n;i++)
{
double minc = INF;
int p = -;
for(int j=;j<n;j++)
{
if(!vis[j] && minc > lowc[j])
{
minc = lowc[j];
p = j;
}
}
if(minc == INF)
return -;
ans += minc;
vis[p] = true;
for(int j=;j<n;j++)
if(!vis[j] && lowc[j] > cost[p][j])
lowc[j] = cost[p][j];
}
return ans;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
int x[maxn];
int y[maxn];
double cost[maxn][maxn];
for(int i=;i<n;i++)
scanf("%d %d",&x[i],&y[i]);
for(int i=;i<n;i++)
{
for(int j=;j<n;j++)
{
if(i == j) {
cost[i][j] = ;
continue;
}
else if(check(dis(x[i],y[i],x[j],y[j]))) {
//cout<<dis(x[i], y[i], x[j], y[j])<<endl;
cost[i][j] = dis(x[i], y[i], x[j], y[j]);
cost[j][i] = dis(x[i], y[i], x[j], y[j]);
}
else if(!check(dis(x[i],y[i],x[j],y[j])))
cost[i][j] = INF;
}
} //cout<<cost[0][1]<<endl;
double ans = Prime(cost,n);
if(ans == -)
puts("oh!");
else
printf("%.1f\n",ans * );
}
}

kuangbin 最小生成树的更多相关文章

  1. kuangbin最小生成树专题

    网址:https://vjudge.net/contest/66965#overview 第一题: poj1251 裸最小生成树 #include<iostream> #include&l ...

  2. [kuangbin带你飞]专题六 最小生成树

    学习最小生成树已经有一段时间了 做一些比较简单的题还算得心应手..花了三天的时间做完了kuangbin的专题 写一个题解出来记录一下(虽然几乎都是模板题) 做完的感想:有很多地方都要注意 n == 1 ...

  3. [kuangbin]专题六 最小生成树 题解+总结

    kuangbin专题链接:https://vjudge.net/article/752 kuangbin专题十二 基础DP1 题解+总结:https://www.cnblogs.com/RioTian ...

  4. [ An Ac a Day ^_^ ] [kuangbin带你飞]专题八 生成树 UVA 10600 ACM Contest and Blackout 最小生成树+次小生成树

    题意就是求最小生成树和次小生成树 #include<cstdio> #include<iostream> #include<algorithm> #include& ...

  5. [kuangbin带你飞]专题六 最小生成树 POJ 2421 Constructing Roads

    给一个n个点的完全图 再给你m条道路已经修好 问你还需要修多长的路才能让所有村子互通 将给的m个点的路重新加权值为零的边到边集里 然后求最小生成树 #include<cstdio> #in ...

  6. [ An Ac a Day ^_^ ][kuangbin带你飞]专题六 最小生成树 POJ 2031 Building a Space Station

    最小生成树模板题 注意最后输出用%f (从C99开始%f已经不能用于输出double 即 输入用%lf 输出用%f) #include<cstdio> #include<algori ...

  7. [kuangbin带你飞]专题六 最小生成树 POJ 1287 Networking

    最小生成树模板题 跑一次kruskal就可以了 /* *********************************************** Author :Sun Yuefeng Creat ...

  8. [ An Ac a Day ^_^ ] [kuangbin带你飞]专题六 最小生成树 POJ 1251 Jungle Roads

    题意: 有n个点 每个点上有一些道路 求最小生成树 解释下输入格式 A n v1 w1 v2 w2 A点上有n条边 A到v1权值是w1 A到v2权值是w2 思路: 字符串处理之后跑kruskal求最小 ...

  9. 最小生成树 kuangbin专题最后一个题

    题目链接:https://cn.vjudge.net/contest/66965#problem/N 注释:这道题需要用krustra,用prim的话可能会超时.并且在计算距离的时候要尽量减少步骤,具 ...

随机推荐

  1. 在Docker容器中安装jdk和spark

    在Docker容器中安装jdk和spark 1.下载jdk和spark 可以使用迅雷等专业下载软件下载jdk和spark软件包,注意是linux版,这里直接给出下载地址: JDK下载地址 JDK进入后 ...

  2. Visual Studio 2012 未找到与约束 ContractName问题,及printf unsafe问题

    1.用VS 2012 创建c++项目失败,提示未找到与约束 ContractName .............的错误 解决办法:下载VS 2012 补丁,很小的一个补丁,不过很管用 地址:http: ...

  3. BestCoder Round #81 (div.2)

    HDU:5670~5764 A题: 是一个3进制计数: #include <bits/stdc++.h> using namespace std; ]; int calc(long lon ...

  4. 【[SCOI2012]喵星球上的点名】

    好题啊 \(SA+ST\text{表}+\text{莫队}\) 我们先强行把所有的串连起来,串与串之间插入特殊字符,姓和名之间也插入特殊字符 之后跑一遍\(SA\),求出\(sa\)和\(het\) ...

  5. 2018.11.29 Struts2中拦截器的学习&项目的实际运用

    struts2官方架构 拦截器的创建 第一种方式 第二种方式 看源码AbstractInterceptor 底层已经帮我们写过这些方法了 第三种方式(推荐) 拦截器API学习 放行 前后处理 不放行, ...

  6. 【Elasticsearch】搜索小记之 match VS match_phrase

    最近稍微研究了一下ElasticSearch(下文简称ES),所谓可扩展的开源弹性搜索解决方案,跟同事笑称,如果它作为SQL SERVER的话,我的了解还在基本的select语句上,当然学习它也是一个 ...

  7. 【luogu P2661 信息传递】 题解

    题目链接:https://www.luogu.org/problemnew/show/P2661#sub 一种利用并查集求最小环的做法: 对于每个同学看作一个点,每次信息传递是一条有向边,当出现最小环 ...

  8. 【题解】P1516 青蛙的约会(Exgcd)

    洛谷P1516:https://www.luogu.org/problemnew/show/P1516 思路: 设两只青蛙跳了T步 则A的坐标为X+mT   B的坐标为Y+nT 要使他们相遇 则满足: ...

  9. [译]GLUT教程 - 安装

    Lighthouse3d.com >> GLUT Tutorial >> Basics >> Setup 你需要什么 要用GLUT库开发程序,你可以下载最新版本3. ...

  10. Mvc5 控制器,视图简单说明

    本系列会比Mvc4更详细.Mvc4记录或没记录的东西这里也会提到. 控制器 自动装配: 一般自动装配对于添加的时候比较好用 视图: 控制器返回的视图,其实就是一些静态的HTML.动态性不好,从控制器传 ...