标签:style blog color io os for sp div on
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include <iostream>
#define eps 1e-8
using namespace std;
/*
最小树形图图模版-朱刘算法
模版说明:点标号必须0-(N-1)
必须去除到自身的点(到自身的边的边权赋无限大)
*/
#define M 109
#define type double
const type inf=1e20;
struct Node{
int u , v;
type cost;
}E[M*M+5];
int pre[M],ID[M],vis[M];
type In[M];
type Directed_MST(int root,int NV,int NE) {
type ret = 0;
while(true) {
//1.找最小入边
for(int i=0;i<NV;i++) In[i] = inf;
for(int i=0;i<NE;i++){
int u = E[i].u;
int v = E[i].v;
if(E[i].cost < In[v] && u != v) {
pre[v] = u;
In[v] = E[i].cost;
}
}
for(int i=0;i<NV;i++) {
if(i == root) continue;
if(In[i] == inf) return -1;//除了跟以外有点没有入边,则根无法到达它
}
//2.找环
int cntnode = 0;
memset(ID,-1,sizeof(ID));
memset(vis,-1,sizeof(vis));
In[root] = 0;
for(int i=0;i<NV;i++) {//标记每个环
ret += In[i];
int v = i;
while(vis[v] != i && ID[v] == -1 && v != root) {
vis[v] = i;
v = pre[v];
}
if(v != root && ID[v] == -1) {
for(int u = pre[v] ; u != v ; u = pre[u]) {
ID[u] = cntnode;
}
ID[v] = cntnode ++;
}
}
if(cntnode == 0) break;//无环
for(int i=0;i<NV;i++) if(ID[i] == -1) {
ID[i] = cntnode ++;
}
//3.缩点,重新标记
for(int i=0;i<NE;i++) {
int v = E[i].v;
E[i].u = ID[E[i].u];
E[i].v = ID[E[i].v];
if(E[i].u != E[i].v) {
E[i].cost -= In[v];
}
}
NV = cntnode;
root = ID[root];
}
return ret;
}
int n,m;
struct Tpoint
{
double x,y;
void in()
{
scanf("%lf%lf",&x,&y);
}
}p[M];
double dis(Tpoint a,Tpoint b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
void init()
{
for(int i=0;i<n;++i)p[i].in();
int h=0;
for(int i=0;i<m;++i){
int x,y;
scanf("%d%d",&x,&y);
if(x==y)continue;
x--;y--;
E[h].u=x;
E[h].v=y;
E[h++].cost=dis(p[x],p[y]);
}
double ans=Directed_MST(0,n,h);
if(ans==-1)puts("poor snoopy");
else
printf("%.2f\n",ans);
}
int main() {
while(scanf("%d%d",&n,&m)!=EOF)
{
init();
}
return 0;
}
自己了一份== g++ wa c++ ac
#include<iostream> #include<cstring> #include<set> #include<map> #include<cmath> #include<stack> #include<queue> #include<deque> #include<list> #include<algorithm> #include<stdio.h> #include<iomanip> #define rep(i,n) for(int i=0;i<n;++i) #define fab(i,a,b) for(int i=a;i<=b;++i) #define fba(i,b,a) for(int i=b;i>=a;--i) #define PB push_back #define MP make_pair #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define sf scanf #define pf printf #define LL long long const int N=105; using namespace std; typedef pair<int,int>PII; #define type double const type inf = 1e20; #define eps 1e-8 struct Edge{ int u,v; type cost; }E[N*N+10]; int pre[N],ID[N],vis[N]; type In[N]; type MST(int root,int n,int m){ type ret=0; while(true){ rep(i,n)In[i]=inf; rep(i,m){ int u=E[i].u; int v=E[i].v; if(E[i].cost < In[v] && u!=v ){ pre[v]=u; In[v]=E[i].cost; } } rep(i,n){ if(i==root)continue; if(In[i]==inf)return -1; } int cntnode=0; memset(ID,-1,sizeof ID); memset(vis,-1,sizeof vis); In[root]=0; rep(i,n){ ret+=In[i]; int v=i; while(vis[v]!=i&&ID[v]==-1&&v!=root){ vis[v]=i; v=pre[v]; } if(v!=root&&ID[v]==-1){ for(int u=pre[v];u!=v;u=pre[u]){ ID[u]=cntnode; } ID[v]=cntnode++; } } if(cntnode==0)break; rep(i,n)if(ID[i]==-1)ID[i]=cntnode++; rep(i,m){ int v=E[i].v; E[i].u=ID[E[i].u]; E[i].v=ID[E[i].v]; if(E[i].u!=E[i].v)E[i].cost-=In[v]; } n=cntnode; root=ID[root]; } return ret; } int n,m; struct Point{ double x,y; void in(){ sf("%lf%lf",&x,&y); } }p[N]; double dis(Point a,Point b){ return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } void init(){ rep(i,n)p[i].in(); int h=0; rep(i,m){ int x,y; sf("%d%d",&x,&y); if(x==y)continue; x--;y--; E[h].u=x; E[h].v=y; E[h++].cost=dis(p[x],p[y]); } double ans=MST(0,n,h); if(ans<0)puts("poor snoopy"); else pf("%.2lf\n",ans+eps); } int main(){ while(sf("%d%d",&n,&m)!=EOF){ init(); } return 0; }
poj 3164 最小树形图模板 (优先c++ ,g++ 有时会wa==)
标签:style blog color io os for sp div on
原文地址:http://www.cnblogs.com/wanggp3/p/4032264.html