首先来发模板 poj 1287
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
using namespace std;
const int maxn=1010;
const int INF=0x3f3f3f3f;
struct Node{
double x,y,h;
}point[maxn];
double mat[maxn][maxn];
double h[maxn][maxn];
double l[maxn][maxn];
int n;
double head,tail;
double dist(Node &a,Node &b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double prim()
{
double ans=0.0,Min;
int vis[maxn];double dis[maxn];
for(int i=0;i<n;i++){
dis[i]=mat[0][i];
vis[i]=0;
}
dis[0]=1;
vis[0]=1;
for(int l=1;l<n;l++){
Min=INF;int pos=-1;
for(int i=0;i<n;i++){
if(!vis[i]&&dis[i]<Min){
Min=dis[i];
pos=i;
}
}
vis[pos]=1;
ans+=Min;
for(int i=0;i<n;i++){
if(!vis[i]&&dis[i]>mat[pos][i]){
dis[i]=mat[pos][i];
}
}
}
return ans;
}
int main()
{
int i,j;
double maxc,minc,maxl,minl,mid;
while(scanf("%d",&n)&&n)
{
maxc=-INF;
minc=INF;
maxl=-INF;
minl=INF;
for(i=0;i<n;i++)
scanf("%lf%lf%lf",&point[i].x,&point[i].y,&point[i].h);
for(i=0;i<n-1;i++)
for(j=i+1;j<n;j++)
{
h[i][j]=h[j][i]=fabs(point[i].h-point[j].h);
l[i][j]=l[j][i]=dist(point[i],point[j]);
if(maxc<h[i][j])
maxc=h[i][j];
if(minc>h[i][j])
minc=h[i][j];
if(maxl<l[i][j])
maxl=l[i][j];
if(minl>l[i][j])
minl=l[i][j];
}
head=minc/maxl;
tail=maxc/minl;
while(tail-head>1e-4)
{
mid=(head+tail)/2;
for(i=0;i<n-1;i++)
for(j=i+1;j<n;j++)
mat[i][j]=mat[j][i]=h[i][j]-mid*l[i][j];
if(prim()<=0.0)
tail=mid;
else
head=mid;
}
printf("%.3f
",head);
}
return 0;
}
然后来发次小生成树的模板 poj 1679
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=10010;
int f[maxn],mst[maxn];
int n,m,t;
struct V
{
int u,v,l;
} a[maxn];
int sf(int x)
{
return x==f[x]?f[x]:f[x]=sf(f[x]);
}
int cmp(V a,V b)
{
return a.l<b.l;
}
void kruskal()
{
int cnt=n-1;
int ant=n-1;
int res1=0;
int res2=0;
for(int i=0; i<=n; i++)f[i]=i;
sort(a,a+m,cmp);
for(int i=0; i<m&&ant; i++)
{
if(sf(a[i].u)!=sf(a[i].v))
{
f[sf(a[i].u)]=sf(a[i].v);
res1+=a[i].l;
ant--;
mst[ant]=i;
}
}
for(int i=0; i<n-1; i++)
{
ant=n-1;
res2=0;
for(int j=0; j<=n; j++)f[j]=j;
for(int j=0; j<m&&ant; j++)
{
if(j==mst[i])continue;
if(sf(a[j].u)!=sf(a[j].v))
{
f[sf(a[j].u)]=sf(a[j].v);
res2+=a[j].l;
ant--;
}
}
//cout<<"2.---"<<ant<<"---"<<res2<<endl;
if(ant!=0)continue;
if(res1==res2){
printf("Not Unique!
");
return;
}
}
cout<<res1<<endl;
}
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(int i=0; i<m; i++)
scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].l);
kruskal();
}
}
再来发最小树形图模板 Poj3164
/*
ID: CUGB-wwj
PROG:
LANG: C++
*/
#include <iostream>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <cmath>
#include <ctime>
#define INF 2000000000
#define MAXN 105
#define MAXM 1005
#define L(x) x<<1
#define R(x) x<<1|1
#define eps 1e-4
using namespace std;
typedef double type;
struct Point
{
double x, y;
}p[MAXN];
struct node
{
int u, v;
type w;
}edge[MAXN * MAXN];
int pre[MAXN], id[MAXN], vis[MAXN], n, m;
type in[MAXN];
double dis(Point a, Point b)
{
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
type Directed_MST(int root, int V, int E)
{
type ret = 0;
while(true)
{
//1.找最小入边
for(int i = 0; i < V; i++) in[i] = INF;
for(int i = 0; i < E; i++)
{
int u = edge[i].u;
int v = edge[i].v;
if(edge[i].w < in[v] && u != v) {pre[v] = u; in[v] = edge[i].w;}
}
for(int i = 0; i < V; i++)
{
if(i == root) continue;
if(in[i] == INF) return -1;//除了跟以外有点没有入边,则根无法到达它
}
//2.找环
int cnt = 0;
memset(id, -1, sizeof(id));
memset(vis, -1, sizeof(vis));
in[root] = 0;
for(int i = 0; i < V; 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] = cnt;
id[v] = cnt++;
}
}
if(cnt == 0) break; //无环 则break
for(int i = 0; i < V; i++)
if(id[i] == -1) id[i] = cnt++;
//3.建立新图
for(int i = 0; i < E; i++)
{
int u = edge[i].u;
int v = edge[i].v;
edge[i].u = id[u];
edge[i].v = id[v];
if(id[u] != id[v]) edge[i].w -= in[v];
}
V = cnt;
root = id[root];
}
return ret;
}
int main()
{
while(scanf("%d%d", &n, &m) != EOF)
{
for(int i = 0; i < n; i++) scanf("%lf%lf", &p[i].x, &p[i].y);
for(int i = 0; i < m; i++)
{
scanf("%d%d", &edge[i].u, &edge[i].v);
edge[i].u--;
edge[i].v--;
if(edge[i].u != edge[i].v) edge[i].w = dis(p[edge[i].u], p[edge[i].v]);
else edge[i].w = INF; //去除自环
}
type ans = Directed_MST(0, n, m);
if(ans == -1) printf("poor snoopy
");
else printf("%.2f
", ans);
}
return 0;
}
最后是最小K度生成树
#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
#include<queue>
#include<algorithm>
#include<climits>
using namespace std;
map<string,int> mp;
int m,n,k;
int g[30][30],dis[30],clo[30],pre[30],fst[30],max_side[30];
const int inf=1000010000;
struct node
{
int v,cap;
node(){}
node(int _v,int _cap):v(_v),cap(_cap){}
bool operator < (const node &dd) const
{
return cap>dd.cap;
}
};
int prim(int src,int id)
{
priority_queue<node> q;
while(!q.empty()) q.pop();
dis[src]=0;
q.push(node(src,0));
int ans=0;
while(!q.empty())
{
node cur=q.top();
q.pop();
int u=cur.v;
if(!clo[u])
{
clo[u]=id;
ans+=dis[u];
for(int i=1;i<n;i++)
{
if(!clo[i]&&g[u][i]!=0&&dis[i]>g[u][i])
{
pre[i]=u;
dis[i]=g[u][i];
q.push(node(i,dis[i]));
}
}
}
}
return ans;
}
void update(int cur,int last,int maxside)
{
max_side[cur]=maxside>g[cur][last]?maxside:g[cur][last];
for(int i=1;i<n;i++)
{
if(i!=last&&g[cur][i]!=0&&(pre[cur]==i||pre[i]==cur))
update(i,cur,max_side[cur]);
}
}
void solve()
{
for(int i=0;i<n;i++)
{
dis[i]=inf;
clo[i]=pre[i]=fst[i]=0;
}
int res=0,cnt=1;
for(int i=1;i<n;i++)
{
if(!clo[i])
res+=prim(i,cnt++);
}
for(int i=1;i<n;i++)
{
int id=clo[i];
if(g[0][i]!=0&&(!fst[id]||g[0][i]<g[0][fst[id]]))
fst[id]=i;
}
for(int i=1;i<cnt;i++)
{
res+=g[0][fst[i]];
g[0][fst[i]]=g[fst[i]][0]=0;
update(fst[i],0,0);
}
k=k-cnt+1;
while(k--)
{
int tmp=0;
for(int i=1;i<n;i++)//kdjfke
{
if(g[0][i]&&(tmp==0||max_side[tmp]-g[0][tmp]<max_side[i]-g[0][i]))
tmp=i;
}
if(max_side[tmp]<=g[0][tmp])
break;
res=res-max_side[tmp]+g[0][tmp];
g[0][tmp]=g[tmp][0]=0;
int p=0;
for(int i=tmp;pre[i]!=0;i=pre[i])
{
if(p==0||g[p][pre[p]]<g[i][pre[i]])
p=i;
}
pre[p]=0;
update(tmp,0,0);
}
printf("Total miles driven: %d
",res);
}
int main()
{
char s1[20],s2[20];
int cap;
while(scanf("%d",&m)!=EOF&&m!=0)
{
mp.clear();
n=1;
memset(g,0,sizeof(g));
mp["Park"]=0;
while(m--)
{
scanf("%s %s %d",s1,s2,&cap);
if(!mp.count(s1)) mp[s1]=n++;
if(!mp.count(s2)) mp[s2]=n++;
int u=mp[s1],v=mp[s2];
if(!g[u][v]||cap<g[u][v])
g[u][v]=g[v][u]=cap;
}
scanf("%d",&k);
solve();
}
return 0;
}