===20180716SHU暑期集训训练赛(3)===

垫底之旅
2016-2017 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2016)

看的题 但没做出来 感觉都在能力范围之内 就是没想到

A: 倒跑并查集 

也蛮难写的 也要把一个点hash成一个值 就是二维变一维嘛

这 怎么想的到

B:tire树上的bfs

tire树都不知道是是什么 你让我怎么做

C:对一副乱序的扑克牌求排有序的最小_交换相邻元素的_操作个数

首先数据规模很小 (最多52张牌嘛)

先想想最暴力的做法咯 就对于给定的一副牌

排序的结果无非是 4!(花色全排列)*2^4(顺序和倒序)种结果 384

例如样例1

2h Th 8c Qh

所有的可能性 1.2h Th Qh 8c

                     2.8c  2h Th Qh 

                还有倒序的,不写了

那验证每一种初态到给定态的检查的方法复杂度要多少啊?

不知道啊 卡住了啊 看题解。。。

怎么就LCS了拉 我怎么不知道什么意思啊?

那就考虑一个更简单的模型

一串乱序的数字序列 需要相邻元素交换几次才能变为不下降序列?

艹 不需要相邻元素 随便交换 艹艹艹艹艹 又tm读错题了

Sorting is done by moving one card at a time fromits current position to a new position in the hand, atthe start, end, or in between two adjacent cards. Whatis the smallest number of moves required to sort agiven hand of cards?

 

枚举4!种排列组合 和2^4 正序 倒序 暴力求解

求出最大的LCS就可以拉

有个小tips:A是王牌 是最大的。。。。wa了好几发 读题读题

看错题太蠢了

F

 推公式 排列组合题 ,没什么难度 但我推不出

见过一道差不多的,没去写,亏了。找了半个小时没找到 算了。

额 我错了 看了那么久 还是看不懂 

抄一遍代码 找感觉吧

额 又看了一遍题目。知道了,感觉有意思。

大意是:给n个矩形,让他们一个一个往上叠,约束条件是 宽严格递减(矩形可以旋转,所以长宽可以交换),求最大高度。(n个矩形都要用到)

1,建图。当时第一步都没想到,鬼知道要长宽相连建图啊,但其实应该知道,这已经不是第一次遇到了。(第二次)

建图前想一想,该怎么建图,如果单纯相连,那图的意义,边的意义,点的意义是什么?

这里主要是边的意义,认为规定 a->b的有向边是这个矩形啊 a为宽,b为高放置。(鬼才想的到,我想不到。)

利用约束条件有对这个图产生了新的限制:一个点最多一个出度(这个点只能做一次宽)

这个图可能有许多连通分支,就挑一个来看,这个连通分支有什么特点

2,已知:输入保证n个矩形能叠起来

那上界,n个点是不是最多n条边?  额,不知道。 

证明一下咯,如果有n+1条边,至少一个点的出度>=2.

有n条边,那连通分支中有一个环,再加一条边,又多一个环,就是说,n+1条边的无向图中有两个环

一个环已经自给自足了,没法有出度的边了,那只能别人进去,有两个别人需要进去的点(环缩点),那势必有一个点需要出度两次。

所以n个点的连通分支最多只有n条边。

考虑下界,n个点的连通分支最少有n-1条边(一棵树,真的不能再少了,再少就两个连通分支了。。。)

所以只有两种情况,n个点n条边,每个点都出度一次

                              n个点n-1条边,有一个点无需出(哪个点不用做宽啊,哪肯定是值最大的那个啊,给我滚去做高啊)

那怎么写啊。。。。。额

抄一波代码

Select Code

#include<bits/stdc++.h>
using namespace std;
#define clr(a, x) memset(a, x, sizeof(a))
#define mp(x, y) make_pair(x, y)
#define pb(x) push_back(x)
#define X first
#define Y second
#define fastin                    \
    ios_base::sync_with_stdio(0); \
    cin.tie(0);
typedef long long LL;
const int N = 5e5;

vector<int>G[N];
int val[N];
int vis[N];
int sz=0;int maxv,deg;
LL ans=0;
map<int,int> id;

void dfs(int u){
    vis[u]=1;
    deg+=G[u].size()-2; //妙啊 一条边贡献两个度数,要是树的话,只有2n-2个总度数
    ans+=LL(val[u])*(G[u].size()-1);
    maxv=max(maxv,val[u]); //维护最大点
    for(auto v:G[u]){
        if(!vis[v]) dfs(v);
    }
}


int main(){
    int n;cin>>n;
    for(int i=0,x,y;i<n;i++){
        cin>>x>>y;
        if(id.find(x)==id.end()) id[x]=++sz,val[sz]=x; //缩点
        if(id.find(y)==id.end()) id[y]=++sz,val[sz]=y;
        G[id[x]].pb(id[y]);
        G[id[y]].pb(id[x]);
    }
    clr(vis,0);
    ans=0;
    for(int i=1;i<=sz;i++){
        if(!vis[i])
        {
            maxv=0,deg=0;
            dfs(i);
            if(deg!=0) ans+=maxv; //是个树加上最大的那个点
        }
    }
    cout<<ans<<endl;
    return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值