K. Color Graph

题意:

给定一个简单图,点个数<=16,删去部分边后,使得该图中无边数为奇数得环,问剩下的边数最大为多少?

思路:

如果一个图中无奇数边的环,那么这个图一定是个二分图。只要枚举二分图的左部,统计所有从左部到右部的边个数,答案就是枚举出的所有边数的最大值。(因为最优解一定也是一个二分图,所以一定会被枚举到)

//赛后补题,只过样例,仅供参考
#include <bits/stdc++.h>
using namespace std;
const int maxn=105;
const int maxm=1e4+5;
struct edge{
int u,v;
}E[maxm];
int tot=0;
void addedge(int u,int v){
E[++tot].u=u;
E[tot].v=v;
}
int color[maxn];
int main(){
int T;
cin>>T;
for(int kase=1;kase<=T;kase++){
int n,m;
scanf("%d%d",&n,&m);
fill(color,color+1+n,0);
tot=0;
for(int i=1;i<=m;i++){
int u,v;
scanf("%d%d",&u,&v);
addedge(u,v);
}
int ans=0;
for(int meijv=0;meijv<=(1<<n)-1;meijv++){
int mj=meijv;
for(int i=1;i<=n;i++){
if(mj&1){
color[i]=1;
}
else color[i]=0;
mj>>=1;
}
int res=0;
for(int i=1;i<=tot;i++){
if(color[E[i].u]!=color[E[i].v]){
res++;
}
}
ans=max(ans,res);
}
printf("Case #%d: %d\n",kase,ans);
}
}

D. Spanning Tree Removal

题意:

给定一个n阶的完全图,每次操作是从图中移除一棵生成树的所有边,问最多能进行多少次这样的操作?输出操作次数和每次移除的生成树的边。

思路:

n阶完全图共有n*(n-1)/2条边,一棵生成树有n-1条边,很容易猜到能进行n/2次操作,接下来就是如何构造的问题。

下面给出一种直接构造的方法(奇数就孤立出一个点随便连即可)

//赛后补题,只过样例,仅供参考
#include <bits/stdc++.h>
using namespace std;
int main(){
int T;
cin>>T;
for(int kase=1;kase<=T;kase++){
int n;
scanf("%d",&n);
printf("Case #%d: %d\n",kase,n/2);
if(n%2==0){
for(int i=1;i<=n/2;i++){
printf("%d %d\n",i,i+1);
for(int j=1;j<=n/2-1;j++){
int u=i+j;
int v=(u+n-j*2-1)%n+1;
printf("%d %d\n",u,v);
printf("%d %d\n",v,u+1);
}
}
}
else{
n--;
for(int i=1;i<=n/2;i++){
printf("%d %d\n",i,i+1);
for(int j=1;j<=n/2-1;j++){
int u=i+j;
int v=(u+n-j*2-1)%n+1;
printf("%d %d\n",u,v);
printf("%d %d\n",v,u+1);
}
printf("%d %d\n",i,n+1);
}
}
}
}

H. Tree Partition

题意:

给出一棵点权树,一个树的大小定义为所有点的权值和。问将一棵树分为k棵子树,如何分割才能使所有树的大小的最大值最小?

思路:

二分答案,已知最大连通子图的大小x后,只要在树上从树根向上dp子树的大小即可。如果一个子树u的大小大于x,则先选择u最大的儿子v切除(即切割边u,v),这样能保证剩下的部分大小尽可能地小。这样保证了图上所有的连通子图的都是小于x的,同时也是用贪心的方法选择切割方案(每个子树都尽可能地取到最大,使剩下部分尽可能小),得到的就是最小的切割次数。

实现方法:若判断发现一个节点u的权值大于x,则将他的儿子节点排序,从大到小依次删除,直到u的权值小于x。

//赛后还原,仅供参考
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e6+5;
struct edge{
int v,next;
}E[maxn];
int head[maxn],tot;
void addedge(int u,int v){
E[++tot].v=v;
E[tot].next=head[u];
head[u]=tot;
}
ll a[maxn],sum[maxn];
int flag=0,cnt;
int n,k;
void dfs(int u,int fa,ll x){
sum[u]=a[u];
if(sum[u]>x||flag==0){
flag=0;
return;
}
for(int i=head[u];i;i=E[i].next){
int v=E[i].v;
if(v!=fa){
dfs(v,u,x);
sum[u]+=sum[v];
}
}
if(sum[u]>x){
vector<ll>V;
for(int i=head[u];i;i=E[i].next){
int v=E[i].v;
if(v!=fa){
V.push_back(sum[v]);
}
}
sort(V.begin(),V.end());
while(sum[u]>x){
cnt++;
sum[u]-=V.back();
V.pop_back();
}
}
if(cnt>k-1){
flag=0;
return;
}
}
bool check(ll x){
flag=1;cnt=0;
dfs(1,0,x);
// printf("%lld:%d\n",x,flag);
if(flag)
return 1;
else
return 0;
}
int main(){
int T;
cin>>T;
for(int kase=1;kase<=T;kase++){
scanf("%d%d",&n,&k);
fill(head,head+1+n,0);
fill(sum,sum+1+n,0);
tot=0;
for(int i=1;i<=n-1;i++){
int u,v;
scanf("%d%d",&u,&v);
addedge(u,v);
addedge(v,u);
}
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
ll l=0,r=1e14+5;//左开右闭
while(r-l>1){
ll mid=(r+l+1)/2;
if(check(mid))
r=mid;
else
l=mid;
}
printf("Case #%d: %lld\n",kase,r);
}
}

E. Cave Escape

题意:

给定一个\(n * m\)的格子矩阵,其中有一个格子是起点,一个格子是终点。从起点开始移动,每次能移动到有相邻边的格子中,每个格子都有一个权值v,若从点a移动到点b,且b点未被访问过,则可以获得\(Va*Vb\)的收益,若移动到终点,可以选择先不出去,继续在图上乱走,问如何可以使得走出终点后获得得收益最大?(只需要输出最大收益即可)

思路:

很显然终点在哪是对答案完全没有影响的,只要在矩阵中乱走获得最大收益再出去即可。

我们可以将这个矩阵转化为一个无向图,图中的点就是矩阵的格点,相邻格点之间有一条边,长度为它们权值的乘积。只要在这个图上跑一遍最大生成树,树的大小就是最大收益。为什么起点也是对答案没有影响?因为要达到最大收益,最好的方法就是将图中每一个都遍历一遍,因为多遍历一个点是不会亏的,可以通过已经遍历到的任意点往新的点走来得到收益(已经遍历过的格子在矩阵中是连通的,可以到处转移),这不就是生成树吗?

//赛后补题,只过样例,仅供参考
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e3+5;
const int maxm=4e6+5;
struct edge{
int u,v;
ll w;
}E[maxm];
bool cmp(edge a,edge b){
return a.w>b.w;
}
int tot=0;
void addedge(int u,int v,ll w){
E[++tot].u=u;
E[tot].v=v;
E[tot].w=w;
}
int fa[maxn*maxn];
int n,m;
int find(int x){
return x==fa[x]?x:fa[x]=find(fa[x]);
}
ll kruskal(){
for(int i=1;i<=n*m;i++){
fa[i]=i;
}
sort(E+1,E+1+tot,cmp);
int cnt=0;
ll ans=0;
for(int i=1;i<=tot;i++){
int u=E[i].u;
int v=E[i].v;
int fu=find(u);
int fv=find(v);
if(fu!=fv){
fa[fu]=fv;
ans+=E[i].w;
cnt++;
}
if(cnt==n*m-1)return ans;
}
}
ll x[maxn*maxn];
ll V[maxn][maxn];
int xx[]={1,0,0,-1};
int yy[]={0,1,-1,0};
int main(){
int T;
cin>>T;
for(int kase=1;kase<=T;kase++){
int sr,sc,tr,tc;
scanf("%d%d%d%d%d%d",&n,&m,&sr,&sc,&tr,&tc);
tot=0;
ll A,B,C,P;
scanf("%lld%lld%lld%lld%lld%lld",&x[1],&x[2],&A,&B,&C,&P);
for(int i=3;i<=n*m;i++){
x[i]=(x[i-1]*A+x[i-2]*B+C)%P;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
V[i][j]=x[(i-1)*m+j];
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
for(int pp=0;pp<4;pp++){
int it=i+xx[pp];
int jt=j+yy[pp];
int u=(i-1)*m+j;
int v=(it-1)*m+jt;
if(it>=1&&it<=n&&jt>=1&&jt<=m){
addedge(u,v,V[i][j]*V[it][jt]);
}
}
}
}
ll ans=kruskal();
printf("Case #%d: %lld\n",kase,ans);
}
}

B. Prefix Code

题意:

给出一系列数字,长度均小于10,问是否有一个数是其他数的前缀?

思路:

Trie树模板题。记录单词的终末,前缀包含的单词个数即可。若一个点是单词终末且前缀包含单词个数>1,则输出No。

//输入字串用s+1,函数调用用s
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int T[maxn][12];
int num[maxn];
int isend[maxn];
int tot=1;
void add(char *s){
int l=strlen(s+1);
int rt=1;
for(int i=1;i<=l;i++){
if(T[rt][s[i]-'0']==0){
T[rt][s[i]-'0']=++tot;
rt=tot;
}
else{
rt=T[rt][s[i]-'0'];
}
num[rt]++;
}
isend[rt]=1;
}
void init(){
for(int i=0;i<=tot;i++){
memset(T[i],0,sizeof(T[i]));
num[i]=isend[i]=0;
}
tot=1;
}
char s[15];
int main(){
int T;
cin>>T;
for(int kase=1;kase<=T;kase++){
init();
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%s",s+1);
add(s);
}
int flag=1;
for(int i=1;i<=tot;i++){
if(isend[i]&&num[i]>1){
flag=0;
break;
}
}
if(flag)
printf("Case #%d: Yes\n",kase);
else
printf("Case #%d: No\n",kase);
}
}

ICPC2019上海区域赛 部分题解(正在更新)的更多相关文章

  1. 2019 ICPC 上海区域赛总结

    2019上海区域赛现场赛总结 补题情况(以下通过率为牛客提交): 题号 标题 已通过代码 通过率 我的状态 A Mr. Panda and Dominoes 点击查看 5/29 未通过 B Prefi ...

  2. UVAlive7141 BombX 14年上海区域赛D题 线段树+离散化

    题意:一个无限大的棋盘, 有n个小兵, 给出了n个兵的坐标, 现在有一个长为width 高为height的炸弹放在棋盘上, 炸弹只能上下左右平移, 不能旋转. 且放炸弹的区域不能含有士兵, 炸弹可以一 ...

  3. 2018-2019 ACM-ICPC 徐州区域赛 部分题解

    题目链接:2018-2019 ACM-ICPC, Asia Xuzhou Regional Contest A. Rikka with Minimum Spanning Trees 题意: 给出一个随 ...

  4. ACM 2015年上海区域赛A题 HDU 5572An Easy Physics Problem

    题意: 光滑平面,一个刚性小球,一个固定的刚性圆柱体 ,给定圆柱体圆心坐标,半径 ,小球起点坐标,起始运动方向(向量) ,终点坐标 ,问能否到达终点,小球运动中如果碰到圆柱体会反射. 学到了向量模板, ...

  5. UVALive 7148 LRIP 14年上海区域赛K题 树分治

    题意 n个点组成一棵树, 带有点权. 求最长不降的路径的长度, 且路径上最大值最小值之差不超过D. 显然是树分治, 但是分治之后如何维护答案呢. 假设当前重心为g, 分别记录g出发不降路径的长度,以及 ...

  6. ICPC2019 亚洲区域赛 南京站

    蒟蒻终于打完了人生的第一场ICPC了. 终榜去星后rank36,AG,和AU差几十罚时了. 虽有遗憾但总体也是正常发挥了. 不愿再去对比赛做什么回顾,甚至很不愿去想.很多题已经在能力之外,即便是平常熟 ...

  7. UVALive 7146 (贪心+少许数据结构基础)2014acm/icpc区域赛上海站

    这是2014年上海区域赛的一道水题.请原谅我现在才发出来,因为我是在太懒了.当然,主要原因是我刚刚做出来. 其实去年我就已经看到这道题了,因为我参加的就是那一场.但是当时我们爆零,伤心的我就再也没有看 ...

  8. 2014年亚洲区域赛北京赛区现场赛A,D,H,I,K题解(hdu5112,5115,5119,5220,5122)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud 下午在HDU上打了一下今年北京区域赛的重现,过了5题,看来单挑只能拿拿铜牌,呜呜. ...

  9. 【2013南京区域赛】部分题解 hdu4802—4812

    上周末打了一场训练赛,题目是13年南京区域赛的 这场题目有好几个本来应该是我擅长的,但是可能是太久没做比赛了各种小错误代码写的也丑各种warusn trush搞得人很不爽 全场题之一的1002也没有想 ...

随机推荐

  1. host文件无操作权限

    把先用其它启动方式启动电脑,如winpe(网上有制作方法,很简单的),启动后找到FWPKCLNT.SYS所在文件夹, 一般在c/windows/system32/drivers,将drivers文件夹 ...

  2. python 更快地判断数字的奇数还是偶数

    使用 按位与运算符(&) 将能更加快速地判断一个整数是奇数还是偶数 使用举例如下: def check_number(n): if n & 1: return '奇数' else: r ...

  3. CSU-1110 RMQ with Shifts (单点更新+区间最小值 zkw线段树)

    In the traditional RMQ (Range Minimum Query) problem, we have a static array A. Then for each query ...

  4. 打乱一个排好序的 list 对象 alist?

    1. import random 2. random.shuffle(alist)

  5. js中的回调地狱 Callback to Hell

        本文重点:解决方式:1.promise  2. 拆解 function:将各步拆解为单个的 function  3. 通过 Generator 函数暂停执行的效果方式 4. 通过ES8的异步函 ...

  6. JVM 运行时数据区域划分

    目录 前言 什么是JVM JRE/JDK/JVM是什么关系 JVM执行程序的过程 JVM的生命周期 JVM垃圾回收 JVM的内存区域划分 一.运行时数据区包括哪几部分? 二.运行时数据区的每部分到底存 ...

  7. 了解Greenplum (2)

    一.目的 1. 理解Greenplum中的数据分布策略(random 和 distribution),分析不同分布策略的优劣:2. 理解查询执行中的数据广播和数据重分布,分析在何种情况下选择哪种策略, ...

  8. 解决SVN异常 cleanup failed

    winndows上偶尔使用SVN的时候就会整出一些有的没的问题,比如"cleanup failed to process the following paths previous opera ...

  9. CentOS 7 FTP的安装与配置

    CentOS7 FTP安装与配置 1.FTP的安装 #安装yum install -y vsftpd #设置开机启动systemctl enable vsftpd.service #启动systemc ...

  10. IncDec Sequence (差分)

    题目地址 这道题可以用来检测一下你是否学会了差分,或者你可以更加透彻的理解差分 我们把 \(cf[]\) (差分)数组拿出了,就可以发现这道题就是每次可以在 \(cf[]\)中 选两个数,一个+1,一 ...