ZZULI 1497 Reading Books

Reading Books

Time Limit:1000MS  Memory Limit:65536K
Total Submit:15 Accepted:2

Description

In the summer vacation,LRJ wants to improve himself incomputer science.So he finds out Nbooks of computer science in the school library.The books are numbered from 0 to N-1.

To finish reading the i-th book,it takes LRJ time[i] minutes.But some books are similar in the content. If the i-th book and the j-th book are similar,then if LRJ has finished reading the i-th book,it will take him only [time[j]/2] minutes to finish reading the j-th book.Of course if LRJ has finished reading the j-th book,it will take him only [time[i]/2] minutes to finish reading the i-th book,Now you are asked to tell LRJ the minimal total time to finish reading all the N books.

Input

The first line contains two integers N (0≤N≤100)and M(0≤M≤N(N-1)/2).N is the total number of books.M is thenumber of pairs which are similar.Then the following N lines describe time[0],time[1],…,time[N-1](1≤time[i]≤10^5).

Next comes M lines ,each contains two integer (i,j),indicating that the i-th book and the j-th book are similar.Input is ended by N=0 and M=0.

Output

For each test case ,just output the minimal total time on a single line.

Sample Input

2 1
6
10
0 1
3 2
1
2
3
0 1
1 2
3 1
2
4
6
0 1
0 0

Sample Output

11
3
10
用两种方法:(DFS)
代码:
#include<stdio.h>
#include<string.h>
int sum,min;
int time[120],num[120][120],flag[120];
void dfs(int n)
{
  int i;
   if(flag[n]==1)return;
    flag[n]=1;
       if(min>time[n])min=time[n];
       for(i=1;i<=num[n][0];i++)
         dfs(num[n][i]);
}
int main()
{
     int m,n,i,a,b;
   while(scanf("%d%d",&m,&n),m!=0||n!=0)
    {
                memset(num,0,sizeof(num));
               memset(flag,0,sizeof(flag));
             sum=0;
           for(i=0;i<m;i++)
          {
                        scanf("%d",&time[i]);
                    sum+=time[i]/2;
          }
                for(i=0;i<n;i++)
          {
                        scanf("%d%d",&a,&b);
                     num[a][++num[a][0]]=b;
                   num[b][++num[b][0]]=a;
           }
                for(i=0;i<m;i++)
          {
                        if(flag[i]==0)
                   {
                                min=time[i];
                             dfs(i);
                          sum=sum-min/2+min;
                       }
                }
                printf("%d\n",sum);
      }
        return 0;
}
并查集代码:
#include<stdio.h>
int num[120];
int root(int n)
{
 if(n!=num[n])
            n=root(num[n]);
  return n;
}
int main()
{
   int m,n,i,sum,a,b,time[120];
     while(scanf("%d%d",&m,&n),m!=0||n!=0)
    {
                for(i=0;i<m;i++)
          {
                        scanf("%d",&time[i]);
                    num[i]=i;
                }
                for(i=0;i<n;i++)
          {
                        scanf("%d%d",&a,&b);
                     a=root(a);
                       b=root(b);
                       if(time[a]<time[b])
                               num[b]=a;
                        else num[a]=b;
           }
                sum=0;
           for(i=0;i<m;i++)
          {
                        if(num[i]==i)
                            sum+=time[i];
                    else sum+=time[i]/2;
             }
                printf("%d\n",sum);
      }
        return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值