• hdu 5312 dp(背包)、二分图或其他姿势


    题意:给出一个二分图(不一定连通),问最多能加多少边,使它仍然是二分图

    BC周年庆第四题,貌似终判再终判之后数据还是有问题```

    据说貌似可以用bitset搞,而且姿势优美是正解```然而我还是用的dp过的

    首先就是用黑白染色判断每个区块的两边点的个数,接着因为要边数最多,所以显然要两边点数尽量接近,所以我就用01背包的方法,计算能够得到的 n/2 内的半边最大点数,中间加入已达到的最大值优化和黑白染色得到单点额外记录而不进入背包的优化```然后从TLE变成了200+ms过,只能说出数据的太执着于单点,如果构造出一张全是两点连线的图,大概妥妥爆炸```这个测试样例好鱼```然后就这样“卡”过去了,大概bitset才是真-正解吧```

      1 #pragma comment(linker, "/STACK:102400000,102400000")
      2 #include<stdio.h>
      3 #include<string.h>
      4 #include<algorithm>
      5 #include<math.h>
      6 using namespace std;
      7 
      8 int head[10005],nxt[200005],point[200005],size=0;
      9 int num[2];
     10 int c[10005],dp[10005];
     11 
     12 int max(int a,int b){
     13     return a>b?a:b;
     14 }
     15 
     16 int min(int a,int b){
     17     return a<b?a:b;
     18 }
     19 
     20 int read(){
     21     int x=0;
     22     char c=getchar();
     23     while(c>'9'||c<'0')c=getchar();
     24     while(c>='0'&&c<='9'){
     25         x=x*10+c-'0';
     26         c=getchar();
     27     }
     28     return x;
     29 }
     30 
     31 void add(int a,int b){
     32     point[size]=b;
     33     nxt[size]=head[a];
     34     head[a]=size++;
     35     point[size]=a;
     36     nxt[size]=head[b];
     37     head[b]=size++;
     38 }
     39 
     40 void dfs(int a,int x){
     41     c[a]=x;
     42     num[x]++;
     43     for(int i=head[a];~i;i=nxt[i]){
     44         int b=point[i];
     45         if(c[b]==-1)dfs(b,!x);
     46     }
     47 }
     48 
     49 int main(){
     50     int T=read();
     51     while(T--){
     52         int n=read();
     53         int m=read();
     54         memset(head,-1,sizeof(head));
     55         size=0;
     56         memset(c,-1,sizeof(c));
     57         int i,j;
     58         if(m==0){
     59             int a=n/2;
     60             printf("%d
    ",a*(n-a));
     61             continue;
     62         }
     63         for(i=1;i<=m;i++){
     64             int a=read();
     65             int b=read();
     66             add(a,b);
     67         }
     68         int cnt=0,ans=0,maxx=0;
     69         memset(dp,-1,sizeof(dp));
     70         dp[0]=0;
     71         int k=0;
     72         for(i=1;i<=n;++i){
     73             if(c[i]==-1){
     74                 num[0]=num[1]=0;
     75                 dfs(i,1);
     76                 if(num[0]+num[1]==1){
     77                     k++;
     78                     continue;
     79                 }
     80                 for(j=min(n/2,maxx+max(num[0],num[1]));j>=0;--j){
     81                     if(j-num[0]>=0&&dp[j-num[0]]==cnt){
     82                         dp[j]=cnt+1;
     83                         maxx=max(maxx,j);
     84                         ans=max(ans,j);
     85                     }
     86                     if(j-num[1]>=0&&dp[j-num[1]]==cnt){
     87                         dp[j]=cnt+1;
     88                         maxx=max(maxx,j);
     89                         ans=max(ans,j);
     90                     }
     91                 }
     92                 cnt++;
     93             }
     94         }
     95         ans=min(ans+k,n/2);
     96         int x1=n-ans;
     97         printf("%d
    ",x1*ans-m);
     98     }
     99     return 0;
    100 }
    View Code
  • 相关阅读:
    JAVA Rest High Level Client如何取聚合后的数据
    elasticsearch中TermQuery查不到数据问题
    项目中redis改brpop阻塞模式为订阅模式的实现(二)
    项目中redis改brpop阻塞模式为订阅模式的实现(一)
    《算法笔记》5. 前缀树、桶排序、排序算法总结
    《算法笔记》4. 堆与堆排序、比较器详解
    《算法笔记》3. 归并排序、随机快排整理
    《算法笔记》2. 链表、栈、队列、递归、哈希表、顺序表
    《算法笔记》1. 复杂度、排序、二分、异或
    深入理解Java线程状态转移
  • 原文地址:https://www.cnblogs.com/cenariusxz/p/4676928.html
Copyright © 2020-2023  润新知