POJ 1344

题意:给定一棵含有n片叶子的树,告诉你每片叶子到其它叶子的距离,求整棵树的权值。

题解:1、假设最后已经生成一棵完整的树,其中某个结点上必定会有至少两片叶子,否则该结点可以直接去掉而不影响最后的结果。

   2、对于这种有两片叶子以上上作为孩子的结点,除该子树的所有的结点到它的叶子都会经过该节点,所以可以直接将该子树缩点变成一个大点,记录这个结点到其他所有点的距离。

     3、反复进行2这种操作,直至最后只剩一个结点。

View Code
 1 #include<cstdio>

 2 #include<cstring>

 3 #include<algorithm>

 4 using namespace std;

 5 int n,go[200][200];

 6 bool vis[200];

 7 bool check(int a,int b,int &sa)

 8 {

 9     bool flag=true;

10     for(int i=0;i<n;i++)

11     {

12         if(!vis[i]&&i!=a&&i!=b)

13         {

14             if(flag)

15             {

16                 sa=go[a][i]-(go[a][i]+go[b][i]-go[a][b])/2;

17                 flag=false;

18             }

19             else if(sa!=go[a][i]-(go[a][i]+go[b][i]-go[a][b])/2)

20                 return false;

21         }

22     }

23     return true;

24 }

25 int main()

26 {

27     //freopen("data.txt","r",stdin);

28     while(scanf("%d",&n),n)

29     {

30         memset(vis,false,sizeof(vis));

31         for(int i=0;i<n;i++)

32         {

33             go[i][i]=0;

34             for(int j=i+1;j<n;j++)

35                 scanf("%d",&go[i][j]),go[j][i]=go[i][j];

36         }

37         int ans=0,sa,a,b;

38         while(1)

39         {

40             bool flag=false;

41             for(a=0;a<n;a++)

42             {

43                 if(vis[a])

44                     continue;

45                 for(b=a+1;b<n;b++)

46                 {

47                     if(vis[b])

48                         continue;

49                     if(check(a,b,sa))

50                     {

51                         flag=true;

52                         break;

53                     }

54                 }

55                 if(flag)

56                     break;

57             }

58             if(!flag)

59                 break;

60             ans+=go[a][b];

61             vis[a]=vis[b]=true;

62             for(int j=0;j<n;j++)

63             {

64                 if(!vis[j])

65                     go[j][n]=go[n][j]=go[j][a]-sa;

66             }

67             n++;

68         }

69         printf("%d\n",ans);

70     }

71     return 0;

72 }

你可能感兴趣的:(poj)