zoukankan      html  css  js  c++  java
  • 开篇词The Start以及[Vjudge][HDU2242]空调教室

    开篇

     

    这是我写的第一篇记录好题的博客,也是博客园上我发布的第一篇博客。

    以后我的所有博客都将在洛谷和博客园上同时发布,同志们有兴趣的在哪里都可以看一看。

    [https://www.luogu.com.cn/blog/DarthVictor/#](洛谷博客)
    [https://www.cnblogs.com/DarthVictor/](博客园)

    那么今天要记录的就是:空调教室!

     

    题目

     

    题面

    众所周知,HDU的考研教室是没有空调的,于是就苦了不少不去图书馆的考研仔们。Lele也是其中一个。而某教室旁边又摆着两个未装上的空调,更是引起人们无限YY。

    一个炎热的下午,Lele照例在教室睡觉的时候,竟然做起了空调教室的美梦。

    Lele梦到学校某天终于大发慈悲给某个教室安上了一个空调。而且建造了了M条通气管道,让整个教学楼的全部教室都直接或间接和空调教室连通上,构成了教室群,于是,全部教室都能吹到空调了。

    不仅仅这样,学校发现教室人数越来越多,单单一个空调已经不能满足大家的需求。于是,学校决定封闭掉一条通气管道,把全部教室分成两个连通的教室群,再在那个没有空调的教室群里添置一个空调。

    当然,为了让效果更好,学校想让这两个教室群里的学生人数尽量平衡。于是学校找到了你,问你封闭哪条通气管道,使得两个教室群的人数尽量平衡,并且输出人数差值的绝对值。

    Input
        
    本题目包含多组数据,请处理到文件结束。

    每组测试第一行包含两个整数N和M(0<N<=10000,0<M<20000)。其中N表示教室的数目(教室编号从0到N-1),M表示通气管道的数目。

    第二行有N个整数Vi(0<=Vi<=1000),分别代表每个教室的人数。
        
    接下来有M行,每行两个整数Ai,Bi(0<=Ai,Bi<N),表示教室Ai和教室Bi之间建了一个通气管道。

    Output

    对于每组数据,请在一行里面输出所求的差值。

    如果不管封闭哪条管道都不能把教室分成两个教室群,就输出"impossible"。

    Sample Input

    4 3

    1 1 1 1

    0 1

    1 2

    2 3

    4 3
        
    1 2 3 5
        
    0 1
        
    1 2
        
    2 3

    Sample Output

    0
        
    1

     

    解说


    这道题用的方法应该是Tarjan边双+缩点,网上大部分的讲解都说要用树形DP,但是还没学到,只能自己再想方法。

    最开始的时候想简单了,觉得求出每个边双连通分量的人数,放进数组里,跑一遍背包,求出把这些数分成两组的最小差值,就行了,样例还过了,就是A不了……被老郭一说才发现这是个图啊,直接当一组数分的话一组可能根本连不起来……

    只不过是从头再来……

    改了改想法,求出边双之后先缩点,变成一棵树,然后……

    我没听说过树形DP是个什么东西啊!

    万能DFS吧。

    随便找一个点作为根节点,DFS过程就是依次往下搜它的儿子,返回值就是它自己的权值加下面子孙的权值,每次加完abs(计算总人数-2 * 自己的人数),然后和ans取最小值。(不知道这个式子怎么来的?差值=(总人数-第一部分人数)-第一部分人数)

    完成!Ура!

    咦?还不对?

    再检查发现犯了两个 极其愚蠢的 错误。边数组开的时候没乘2,ans初始值设成了1000(应为10000000,万一有10001个点,其中10000个一撮,每个点的权值都为1000呢?)

    幸甚至哉,歌以咏志。

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 const int maxn=10000+5,maxe=2*20000+5;
      4 int head[maxn],dfn[maxn],low[maxn],rs[maxn],f[maxn],belong[maxn];
      5 int h[maxn],ans;
      6 bool bridge[maxe],vis[maxn];
      7 int n,m,tot,sum,dfs_clock;bool judge;
      8 struct edge{
      9     int to,next;
     10 }e[maxe],ed[maxe];
     11 void Add(int a,int b){
     12     e[tot].to=b;
     13     e[tot].next=head[a];
     14     head[a]=tot;
     15     tot++;
     16 }
     17 void tarjan(int u,int id){
     18     dfn[u]=low[u]=++dfs_clock;
     19     for(int i=head[u];i;i=e[i].next){
     20         if(i==(id^1)) continue;
     21         int v=e[i].to;
     22         if(!dfn[v]){
     23             tarjan(v,i);
     24             low[u]=min(low[u],low[v]);
     25             if(dfn[u]<low[v]){
     26                 judge=1;
     27                 bridge[i]=bridge[i^1]=1;
     28             }
     29         }
     30         else low[u]=min(low[u],dfn[v]);
     31     }
     32 }
     33 void dfs(int x,int id){
     34     vis[x]=1;
     35     f[id]+=rs[x];
     36     belong[x]=id;
     37     for(int i=head[x];i;i=e[i].next){
     38         if(!bridge[i]&&!vis[e[i].to]) dfs(e[i].to,id);
     39     }
     40 }
     41 int dfs2(int x){
     42     vis[x]=1;
     43     for(int i=h[x];i;i=ed[i].next){
     44         int to=ed[i].to;
     45         if(!vis[to]) f[x]+=dfs2(to);
     46     }
     47     ans=min(ans,abs(sum-2*f[x]));
     48     return f[x];
     49 }
     50 int main(){
     51     while(scanf("%d%d",&n,&m)!=EOF){
     52         tot=2; sum=0; judge=0; dfs_clock=0;
     53         memset(f,0,sizeof(f));
     54         memset(e,0,sizeof(e));
     55         memset(h,0,sizeof(h));
     56         memset(ed,0,sizeof(ed));
     57         memset(dfn,0,sizeof(dfn));
     58         memset(low,0,sizeof(low));
     59         memset(vis,0,sizeof(vis));
     60         memset(head,0,sizeof(head));
     61         memset(belong,0,sizeof(belong));
     62         memset(bridge,0,sizeof(bridge));
     63         for(int i=1;i<=n;i++){
     64             scanf("%d",&rs[i]);
     65             sum+=rs[i];
     66         }
     67         for(int i=1;i<=m;i++){
     68             int a,b;
     69             scanf("%d%d",&a,&b);
     70             Add(a+1,b+1);
     71             Add(b+1,a+1);
     72         }
     73         for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i,head[i]);
     74         if(!judge){
     75             printf("impossible
    ");
     76             continue;
     77         }
     78         int id=0;
     79         for(int i=1;i<=n;i++) {
     80             if(!belong[i]){
     81                 id++;
     82                 dfs(i,id);
     83             }
     84         }
     85         tot=2;
     86         for(int i=1;i<=n;i++){
     87             for(int j=head[i];j;j=e[j].next){
     88                 int from=belong[i],to=belong[e[j].to];
     89                 if(from!=to){
     90                     ed[tot].to=to;
     91                     ed[tot].next=h[from];
     92                     h[from]=tot;
     93                     tot++;
     94                     /*ed[tot].to=from;
     95                     ed[tot].next=h[to];
     96                     h[to]=tot;
     97                     tot++;*/
     98                 }
     99             }
    100         }
    101         ans=10000000;
    102         memset(vis,0,sizeof(vis));
    103         dfs2(1);
    104         printf("%d
    ",ans);
    105     }
    106 
    107 }
    看看代码吧
  • 相关阅读:
    手把手教你利用create-nuxt-app脚手架创建NuxtJS应用
    初识NuxtJS
    webpack打包Vue应用程序流程
    用选择器代替表格列的筛选功能
    Element-UI
    Spectral Bounds for Sparse PCA: Exact and Greedy Algorithms[贪婪算法选特征]
    Sparse Principal Component Analysis via Rotation and Truncation
    Generalized Power Method for Sparse Principal Component Analysis
    Sparse Principal Component Analysis via Regularized Low Rank Matrix Approximation(Adjusted Variance)
    Truncated Power Method for Sparse Eigenvalue Problems
  • 原文地址:https://www.cnblogs.com/DarthVictor/p/12418859.html
Copyright © 2011-2022 走看看