zoukankan      html  css  js  c++  java
  • 2019 西安邀请赛 D

     1 //n件物品,m种关系,(有关系的2个不能在同一组)
     2 //把所有物品分为2组,希望最后2组的差值尽可能小,输出较大者
     3 /*
     4 二分图涂色+可行性(01)背包
     5 dp[i]  =1表示 最后差值为i可行
     6 建图后,对于每个连通分量记录差值,来求所有的可行
     7 */
     8 #include<bits/stdc++.h>
     9 using namespace std;
    10 int  t,n,m;
    11 #define N 250
    12 #define M 102000
    13 int a[N],head[N],sum;
    14 int cnt,vis[N];
    15 int dp[M],dp1[M];
    16 int     sum1=0,sum2=0;
    17 void init(){
    18     cnt  = 0;
    19     for(int i =0;i<N;i++) {
    20         head[i] = -1;
    21         vis[i]  =0;//多组输入
    22     }
    23 }
    24 struct Node{
    25     int u,v,nex;
    26 }e[N*2];
    27 void add(int u,int  v)
    28 {
    29     e[cnt].u=u;e[cnt].v=v;
    30     e[cnt].nex=head[u];head[u]=cnt++;
    31 }
    32 void dfs(int x,int rt){
    33     vis[x] = 1;
    34     if(rt==0)
    35     sum1+=a[x];
    36     else{
    37         sum2+=a[x];
    38     }
    39     for(int i =head[x];i!=-1;i=e[i].nex){
    40         int v = e[i].v;
    41         if(!vis[v])
    42         dfs(v,rt^1);//0^1=1,1^1=0
    43     }
    44 }
    45 int main()
    46 {
    47     scanf("%d",&t);
    48     while(t--)
    49     {
    50         init();
    51         scanf("%d%d",&n,&m);
    52         int x,y;
    53         sum =0;
    54         for(int i =1;i<=n;i++) 
    55         {
    56             scanf("%d",&a[i]);
    57             sum+=a[i]/100;
    58             a[i]/=100;//题目说明都是100的倍数
    59         }
    60         for(int i =0;i<m;i++) {
    61             scanf("%d%d",&x,&y);
    62             add(x,y);add(y,x);//无向图
    63         }
    64     
    65         int num;
    66         for(int i =0;i<=sum;i++) dp[i] = 0;
    67         dp[0] = 1;//dp[0]一定先设为1,来引入第一个差值
    68         for(int i =1;i<=n;i++) {
    69             if(!vis[i]){
    70                 sum1=0,sum2=0;
    71                 dfs(i,0);
    72                 num = abs(sum1-sum2);
    73                 //printf("%d %d %d
    ",sum1,sum2,num);
    74                 for(int j=sum;j>=0;j--){
    75                     if(dp[j]){
    76                         //如 :0,j. 0 ,num 或者 j,0.0,num
    77                         if(abs(j+num)<=sum) dp1[abs(j+num)] =1;
    78                         dp1[abs(j-num)]  =1;
    79                     }
    80                 }
    81                 for(int j =sum;j>=0;j--){
    82                     dp[j]  = dp1[j],dp1[j] = 0;
    83                 }
    84             }
    85         }
    86         //一定需要2个dp 数组,利用dp1一直更新到所有的物品都取完
    87         for(int i =0;i<=sum;i++) {
    88             if(dp[i]){
    89                 
    90                 printf("%d
    ",(sum+i)/2*100);
    91                 break;
    92             }
    93         }
    94     }
    95     return 0;
    96 }
  • 相关阅读:
    eclipse中如何修改编码格式
    如何让Div中的Table居中
    EL表达式和标准标签库
    jQuery获取option的一些常用方法
    第三十五章——过滤器和监听器
    第三十四章——java web的注册登录和留言板的制作
    关于九大内置对象的补充——application
    第三十三章——javaweb初识和九大内置对象
    学习记录
    从 HTTP 到 HTTPS 再到 HSTS
  • 原文地址:https://www.cnblogs.com/tingtin/p/11625160.html
Copyright © 2011-2022 走看看