新单词unidirectional get T T
求有向图上,以某点为根的,最小生成树
参考别人的模板
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<iostream>
#include<algorithm>
#include<cmath>
#define inf 2000000000
using namespace std;
struct node1
{
double x,y;
}p[110];
struct node
{
int u,v;
double w;
}e[10010];
double ans,in[110];
int n,m,r,cnt,id[110],vis[110],pre[110];
int zhuliu(int r,int V,int E)
{
ans=0;
while(1)
{
int u,v,i;
//找最小入边
for(i=0;i<=V;i++)
in[i]=inf;
for(i=0;i<E;i++)
{
u=e[i].u;
v=e[i].v;
if(e[i].w<in[v] && u!=v)
{
pre[v]=u;
in[v]=e[i].w;
}
}
for(i=0;i<V;i++)//判断图不连通 直接返回
if(i!=r&&in[i]==inf) return -1;
//找环
cnt=0;//记缩点后的联通块编号
memset(id,-1,sizeof id);//id[i]表示i缩点后在哪个联通块
memset(vis,-1,sizeof vis);
in[r]=0;
for(i=0;i<V;i++)
{
// printf("i:%d ini:%.2lf\n",i,in[i]);
ans+=in[i];
v=i;
while(vis[v]!=i&&v!=r&&id[v]==-1)//找环
{
vis[v]=i;
v=pre[v];
}
if(v!=r&&id[v]==-1)//缩点
{
for(u=pre[v];u!=v;u=pre[u])
id[u]=cnt;
id[v]=cnt++;
}
}
if(cnt==0) break;//无环
//建新图
for(i=0;i<V;i++)
if(id[i]==-1) id[i]=cnt++;
for(i=0;i<E;i++)
{
u=e[i].u;
v=e[i].v;
e[i].u=id[u];
e[i].v=id[v];
if(id[u]!=id[v]) e[i].w-=in[v];
}
V=cnt;
r=id[r];
}
return 1;
}
int main()
{
int i,a,b;
while(~scanf("%d%d",&n,&m))
{
for(i=1;i<=n;i++)
scanf("%lf%lf",&p[i].x,&p[i].y);
for(i=0;i<m;i++)
{
scanf("%d%d",&a,&b);
e[i].u=a-1;
e[i].v=b-1;
if(a==b) e[i].w=inf;//除掉自环
else e[i].w=sqrt((p[a].x-p[b].x)*(p[a].x-p[b].x)+(p[a].y-p[b].y)*(p[a].y-p[b].y));
}
if(zhuliu(0,n,m)==1)
printf("%.2lf\n",ans);
else printf("poor snoopy\n");
}
return 0;
}