pku 3164最小树形图

记住,这是china算法,呵呵,一丝悲哀,又有一丝欣慰

第一次做,用的是矩阵版本的,但貌似对于数据更大的情况要用邻接表的,继续学习

View Code
#include<stdio.h>
#include
<math.h>
#include
<string.h>
#define INF 100000000
#define min(a,b) a<b?a:b
int n,m;
double map[110][110];
int vis[110],pre[110];
int circle[110];
struct {
int x,y;
}node[
110];
double dist(int i,int j)
{
return sqrt(1.0*(node[i].x-node[j].x)*(node[i].x-node[j].x)+1.0*(node[i].y-node[j].y)*(node[i].y-node[j].y));
}
void dfs(int t)
{
if(vis[t])
return;
vis[t]
=1;
for(int i=1;i<=n;i++)
if(map[t][i]<INF)
dfs(i);
}
bool connect()//判断是否有最小树形图
{
dfs(
1);
for(int i=1;i<=n;i++)
if(!vis[i])
return false;
return true;
}
double china()
{
double ans=0;
int i,j,k;
memset(circle,
0,sizeof(circle));//如果某点被删除,circle[i]=1;
while(1)
{
for(i=2;i<=n;i++)//求出每个点的最小入弧
{
if(circle[i])//
continue;
map[i][i]
=INF;
pre[i]
=i;
for(j=1;j<=n;j++)
{
if(circle[j])
continue;
if(map[j][i]<map[pre[i]][i])
pre[i]
=j;
}
}
for(i=2;i<=n;i++)//遍历找环,判断i在不在环上
{
if(circle[i])
continue;
j
=i;
memset(vis,
0,sizeof(vis));
while(!vis[j]&&j!=1)//相当于一个环从一点一直往pre方向退,
//直到退回自己(即找到了环),或者退到1,即无环
{
vis[j]
=1;
j
=pre[j];
}
if(j==1)//i不在环上
continue;
i
=j;//找到了环
ans+=map[pre[i]][i];
for(j=pre[i];j!=i;j=pre[j])//加上环上的权值
{
ans
+=map[pre[j]][j];
circle[j]
=1;
}
for(j=1;j<=n;j++)
{
if(circle[j]) continue;
if(map[j][i]<INF)//注意:i为环的起点
map[j][i]-=map[pre[i]][i];//更新i的入弧
}
for(j=pre[i];j!=i;j=pre[j])//i点即为 缩环后的点
{
for(k=1;k<=n;k++)
{
if(circle[k])
continue;
if(map[j][k]<INF)
map[i][k]
=min(map[i][k],map[j][k]);//出环的边
if(map[k][j]<INF)
map[k][i]
=min(map[k][i],map[k][j]-map[pre[j]][j]);//入环的边
}
}
break;
}
if(i>n)
{
for(j=2;j<=n;j++)
{
if(circle[j])
continue;
ans
+=map[pre[j]][j];
}
break;
}
}
return ans;
}
int main()
{
int i,j,a,b;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(i=1;i<=n;i++)
scanf(
"%d%d",&node[i].x,&node[i].y);
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
map[i][j]
=INF;
for(i=1;i<=m;i++)
{
scanf(
"%d%d",&a,&b);
map[a][b]
=dist(a,b);
}
memset(vis,
0,sizeof(vis));
if(!connect())
printf(
"poor snoopy\n");
else printf("%.2f\n",china());
}
return 0;
}

  

posted @ 2011-09-06 11:44  Because Of You  Views(289)  Comments(0Edit  收藏  举报