P2872 [USACO07DEC]Building Roads S
传送门已部署
这个题和P1991 无线通讯网很像,几乎是一模一样,只需要更换部分代码就好了,思路就不解释了
#include<bits/stdc++.h>
using namespace std;
#define maxn 1000005
typedef double dd;
int n,m,a,b,tot=0,fa[maxn];
dd ans=0;
struct arr{
int fr,to;
double w;
}edge[maxn];
struct brr{
double x,y;
}point[maxn];
void add(int u,int v,double w){
edge[++tot].fr=u;
edge[tot].to=v;
edge[tot].w=w;
}
dd abc(dd x1,dd x2,dd y1,dd y2){
return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
int cmp(arr x,arr y){
return x.w<y.w;
}
void init(){
for(int i=1;i<=n;i++)
fa[i]=i;
return ;
}
int find(int x){
if(fa[x]==x)
return x;
else{
fa[x]=find(fa[x]);
return fa[x];
}
}
int getf(int v){
if(fa[v]==v)
return v;
else{
fa[v]=getf(fa[v]);
return fa[v];
}
}
int merge(int x,int y){
int t1=getf(x);
int t2=getf(y);
if(t1!=t2){
fa[t2]=t1;
return 1;
}
else
return 0;
}
void k(){
int cout=0;
for(int i=1;i<=tot;i++){
if(merge(edge[i].fr,edge[i].to)) {
ans+=edge[i].w;
cout++;
}
if(cout==n-1)
break;
}
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++)
scanf("%lf%lf",&point[i].x,&point[i].y);
for(int i=1;i<=m;i++){
scanf("%d%d",&a,&b);
add(a,b,0);
}
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
add(i,j,abc(point[i].x,point[j].x,point[i].y,point[j].y));
}
}
sort(edge+1,edge+tot+1,cmp);
init();
k();
printf("%.2f\n",ans);
}
P4779 【模板】单源最短路径(标准版)
这个题是P3371 【模板】单源最短路径(弱化版)的升级版,我用弱化版的直接提交的话,只有16分,主要就是卡在了找最小值的这里,因为我们都去试了一遍全部的值,所以说就要优化
队列,它们是先入先出的,这很容易用平常的排队来理解。但是如果这个队列要支持有紧急情况的人先出队呢?原先那种队列就不再适用了,我们需要使用本文所提到的特殊队列---优先队列
推荐视频:b站BV1P64y1h7dk
我们因此引出用优先队列,来按照我们特定的规定来形成我们的堆
使用堆,来找到一个一个的最小值,这样就节省了时间
思路没有变,只是实现过程变了
#include<bits/stdc++.h>
using namespace std;
#define maxn 500005
#define mod 2147483647111
typedef long long ll;
struct arr{
ll v,w,next;
}g[maxn];
int n,m,s,tot=0,dis[maxn];
ll x,y,z,head[maxn];
void add(int u,int v,int w){
tot++;
g[tot].v=v;
g[tot].w=w;
g[tot].next=head[u];
head[u]=tot;
}
void init(){
for(int i=1;i<=n;i++)
dis[i]=;
dis[s]=0;
return ;
}
struct node{
ll d,u;//d为距离,u是起点
bool operator<(const node&t)const{
return d>t.d;
}
};
void Dijkstra(){
priority_queue<node>q;
q.push((node){0,s});
while(!q.empty()){
node tmep=q.top();
q.pop();
ll u=tmep.u,d=tmep.d;
if(d!=dis[u])
continue;
for(int i=head[u];i;i=g[i].next){
ll v=g[i].v,w=g[i].w;
if(dis[u]+w<dis[v]){
dis[v]=dis[u]+w;
q.push((node){dis[v],v});
}
}
}
}
int main(){
scanf("%d%d%d",&n,&m,&s);
for(int i=1;i<=m;i++){
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);
}
init();
Dijkstra();
for(int i=1;i<=n;i++)
printf("%llu ",dis[i]);
}
可以参考这个视频理解:BV1Kq4y147ac