zoukankan      html  css  js  c++  java
  • BZOJ4886 [Lydsy1705月赛]叠塔游戏[基环树]

    很妙的一道题。

    由于本人过于zz,不会这道题,通过厚颜无耻翻阅题解无数终于懂了这道题,所以这里转载一位神仙的blog

    没有看懂?没事,再来一篇

    这题个人认为主要在于转化题意和建图,这两点想通了应该就不难了。

    转化题意:每个长只要互不相等即可,不管什么严格大于。

    建图:限制了每个长只能被选一次,另一边作为价值。有没有条件限制感觉和上一篇博客相像?长和宽代表的两个点之间建一条边,从长到宽的方向代表以长为底,反向则以宽为底。然后限制每个点出度最多为1.

    图建出来,我们只要定向时满足每个点至多出度为1,就可以。题目有保证了有解,也就是不会出现有点迫不得已出度超过1的情况,所以我们只要放心讨论怎么怎么定向使得入度对应的点权最大即可。

    然后发现并不需要定向,按照上面地址里的方法讨论连通性即可。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 #include<queue>
     7 #include<map>
     8 #define dbg(x) cerr << #x << " = " << x <<endl
     9 #define dbg2(x,y) cerr<< #x <<" = "<< x <<"  "<< #y <<" = "<< y <<endl
    10 using namespace std;
    11 typedef long long ll;
    12 typedef double db;
    13 typedef pair<int,int> pii;
    14 template<typename T>inline T _min(T A,T B){return A<B?A:B;}
    15 template<typename T>inline T _max(T A,T B){return A>B?A:B;}
    16 template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,1):0;}
    17 template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,1):0;}
    18 template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
    19 template<typename T>inline T read(T&x){
    20     x=0;int f=0;char c;while(!isdigit(c=getchar()))if(c=='-')f=1;
    21     while(isdigit(c))x=x*10+(c&15),c=getchar();return f?x=-x:x;
    22 }
    23 const int N=250000+7;
    24 int n;
    25 struct thxorz{int to,nxt;}G[N<<1];
    26 int Head[N<<1],cnt,tot,edge,vertex,maxv;
    27 ll ans;
    28 inline void Addedge(int x,int y){
    29     G[++tot].to=y,G[tot].nxt=Head[x],Head[x]=tot;
    30     G[++tot].to=x,G[tot].nxt=Head[y],Head[y]=tot;
    31 }
    32 int deg[N<<1],val[N<<1],vis[N<<1];
    33 map<int,int> mp;
    34 #define y G[j].to
    35 inline int dfs(int x){
    36     vis[x]=1;++vertex;edge+=deg[x];
    37     MAX(maxv,val[x]);ans+=(deg[x]-1)*1ll*val[x];
    38     for(register int j=Head[x];j;j=G[j].nxt)if(!vis[y])dfs(y);
    39 }
    40 #undef y
    41 int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout);
    42     read(n);
    43     for(register int i=1,x,y;i<=n;++i){
    44         read(x),read(y);
    45         int cx=mp.find(x)==mp.end()?mp[x]=++cnt:mp[x];
    46         int cy=mp.find(y)==mp.end()?mp[y]=++cnt:mp[y];
    47         Addedge(cx,cy);++deg[cx],++deg[cy],val[cx]=x,val[cy]=y;
    48     }
    49     for(register int i=1;i<=cnt;++i)if(!vis[i]){
    50         edge=vertex=maxv=0;dfs(i);edge>>=1;
    51         if(edge<vertex)ans+=maxv;
    52     }
    53     return printf("%lld
    ",ans),0;
    54 }
    View Code

    总结:这种神仙建图题没有办法总结。只能积累技巧,善于转化问题。

  • 相关阅读:
    PHP mysqli_get_client_version() 函数
    PHP mysqli_get_client_stats() 函数
    两台服务器配置互信
    (转)SQL server 容易让人误解的问题之 聚集表的物理顺序问题
    DML操作对索引的影响
    sqlserver 常用语句
    聚集索引
    表扫描
    sqltext的参数化处理
    sqlserver的执行计划
  • 原文地址:https://www.cnblogs.com/saigyouji-yuyuko/p/11688292.html
Copyright © 2011-2022 走看看