http://acm.hdu.edu.cn/showproblem.php?pid=3551

题意:给出一个图,还有一个子图的度数,求有没有办法通过删边使得原图的度数变成那个子图的度数?

思路:我们考虑把每个点拆成du[i]-d[i]个点,代表要删去的度数,然后对于每条边,我们建立两个点eu,ev,eu与ev连边,如果这条边连接了i,j两个点,那么所有的i的点向eu连边,所有的j向ev连边,如果有完美匹配(就是所有点都有匹配)那么有解。

至于为什么:如果eu和ev是匹配边,代表这条边不删,因为这条边的两侧,也就是连接的两个点都有其他的匹配了,那么这条边就不用删。

如果这条边不是匹配边,那么说明i和eu匹配了,j和ev匹配了,这条边代表删掉了,而i和j的度数也-1了

#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
struct edge{int u,v;
}e[2005];
int n,m,p[2005],q[20005];
int match[1005],newbase;
int inqueue[1005],inpath[1005],G[1005][1005],inblossom[1005],father[1005];
int du[1005],d[1005],c[500005],base[1005],start,finish,head,tail;
int read(){int t=0,f=1;char ch=getchar();while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}return t*f;
}
int lca(int u,int v){memset(inpath,0,sizeof inpath);while (1){u=base[u];inpath[u]=1;if (!match[u]) break;u=father[match[u]];}while (1){v=base[v];if (inpath[v]) break;v=father[match[v]];}return v;
}
void reset(int u){while (u!=newbase){int v=match[u];inblossom[base[v]]=inblossom[base[u]]=1;u=father[v];if (base[u]!=newbase) father[u]=v;}
}
void blossomcontract(int u,int v){newbase=lca(u,v);memset(inblossom,0,sizeof inblossom);reset(u);reset(v);if (base[u]!=newbase) father[u]=v;if (base[v]!=newbase) father[v]=u;for (int i=1;i<=n;i++) if (inblossom[base[i]]){base[i]=newbase;if (!inqueue[i]) c[++tail]=i,inqueue[i]=1;}
}
void findaugmentingpath(){memset(inqueue,0,sizeof inqueue);memset(father,0,sizeof father);for (int i=1;i<=n;i++) base[i]=i;head=1;tail=1;c[1]=start;inqueue[start]=1;finish=0;while (head<=tail){int u=c[head++];for (int v=1;v<=n;v++)if (G[u][v]&&base[u]!=base[v]&&match[v]!=u){if (v==start||(match[v]>0)&&(father[match[v]]>0)){blossomcontract(u,v);}elseif (father[v]==0){father[v]=u;if (match[v]){c[++tail]=match[v];inqueue[match[v]]=1;}else{finish=v;return;}}}}
}
void augmentpath(){int u,v,w;u=finish;while (u>0){v=father[u];w=match[v];match[u]=v;match[v]=u;u=w;}
}
bool solve(){int res=0;memset(match,0,sizeof match);for (int i=1;i<=n;i++)if (!match[i]){start=i;findaugmentingpath();if (finish) augmentpath(),res++;}for (int i=1;i<=n;i++)if (!match[i]) return 0;return 1;
}
bool build(){memset(G,0,sizeof G);int cnt=0;for (int i=1;i<=n;i++)if (du[i]>d[i]) return 0;memset(p,0,sizeof p); for (int i=1;i<=m;i++){if (!p[e[i].u]){p[e[i].u]=++cnt;q[e[i].u]=cnt+d[e[i].u]-du[e[i].u]-1;cnt=cnt+d[e[i].u]-du[e[i].u]-1;}if (!p[e[i].v]){p[e[i].v]=++cnt;q[e[i].v]=cnt+d[e[i].v]-du[e[i].v]-1;cnt=cnt+d[e[i].v]-du[e[i].v]-1;}int k=cnt+2;cnt+=2;G[k][k-1]=G[k-1][k]=1;for (int j=p[e[i].u];j<=q[e[i].u];j++) G[j][k-1]=G[k-1][j]=1;for (int j=p[e[i].v];j<=q[e[i].v];j++) G[j][k]=G[k][j]=1;}n=cnt;return 1;
}
int main(){int Tcase=0;int T=read();while (T--){n=read();m=read();printf("Case %d: ",++Tcase);memset(d,0,sizeof d);for (int i=1;i<=m;i++){e[i].u=read();e[i].v=read();d[e[i].u]++;d[e[i].v]++;}for (int i=1;i<=n;i++) du[i]=read();if (build()&&solve()){printf("YES\n");}else{printf("NO\n");}}return 0;
}

转载于:https://www.cnblogs.com/qzqzgfy/p/5683813.html

HDU 3551 Hard Problem相关推荐

  1. HDU - 3551 Hard Problem(一般图最大匹配)

    题目链接:点击查看 题目大意:给出一张无向图,问能否删除任意数量的边,使得每个点的度数都达到指定的数值 题目分析:参考博客:https://www.cnblogs.com/xiongtao/p/111 ...

  2. hdu A + B Problem II(大数相加,数组实现)

    hdu A + B Problem II(大数相加,数组实现) 题目走起 注意最后一个case 不需要换行 下面代码 #include<stdio.h> #include<strin ...

  3. HDU.1001 Sum Problem

    原题 HDU.1001 Sum Problem 分类 杂题 题意 计算从1到正整数n的累加和. 输入/输出 要求与格式 输入内容 每行输入一个正整数 输出结果 结果为累加和 输出格式 每个输出结果独占 ...

  4. [HDU 5445]Food Problem[多重背包]

    题目链接:[HDU 5445]Food Problem[多重背包] 题意分析: 有n种类型的点心,每种提供t的能量,占据u的空间,有v个: 有m种类型的卡车,每种容量x,雇佣花费y,能提供z辆: 点心 ...

  5. hdu 3549 Flow Problem(最大流模板题)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3549 Problem Description Network flow is a well-known ...

  6. hdu 1023 Train Problem II

    题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=1212 Train Problem II Description As we all know the ...

  7. HDU 5427 A problem of sorting 水题

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5427 A problem of sorting Time Limit: 2000/1000 MS ( ...

  8. HDU 1022[Train Problem I] 栈的应用

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1022 题目大意:一列序列为s1的车厢是否能通过车站的中转以序列s2出站.白皮上有. 关键思想:栈的应用 ...

  9. HDU 3549 Flow Problem (dinic模版 isap模版)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3549 题意: 给你一个有向图,问你1到n的最大流. dinic模版 (n*n*m) 1 #includ ...

  10. hdu 3374 String Problem (字符串最小最大表示 + KMP求循环节)

    Problem - 3374 KMP求循环节. http://www.cnblogs.com/wuyiqi/archive/2012/01/06/2314078.html 循环节推导的证明相当的好,这 ...

最新文章

  1. java过滤器命名_java--FilenameFilter文件过滤器
  2. python空值填充为固定值_Python基础:numpy中空值怎样设置
  3. 软件构造的视图与质量指标
  4. Prim算法和Kruskal算法
  5. Ajax异步与JavaScript的一些初浅认识
  6. 用Java读取文件的5种方法-BufferedReader,FileInputStream,文件,扫描仪,RandomAccessFile
  7. Android创建并响应选项菜单
  8. Unity使用FGUI的基本操作(一)
  9. 软件测试文档类型有哪些?
  10. wox wpm 安装 有道插件
  11. 4am永远 鼠标按键设置_罗技的MX Master鼠标是苹果Mac系统下最好的鼠标
  12. win10电脑开启卓越性能
  13. python提取一句话中的数字_从Python的字符串列表中提取数字
  14. exceptions - Pitfall: the Lost Exception
  15. 计算机考研408真题(全国统考2009--2020)、985高校计算机考研资料(清北+北理+北邮+武大+华科+浙大+复旦+哈工大+西安交大+华南理工)、王道四件套、天勤四件套---百度网盘免费下载
  16. javascript事件侦听器是什么东西,用来干哈子
  17. python习题练习
  18. 初识CityEngine
  19. 【macOS免费软件推荐】第3期:ProperTree
  20. Python爬虫违法吗?如何判断爬虫采集内容是否违法?

热门文章

  1. OpenCV中ROI
  2. 如何导出微信的小视频
  3. pip更新导致ImportError: cannot import name ‘InvalidSchemeCombination‘ from ‘pip._internal.exceptions‘
  4. 实习成长之路:MySQL十二:为什么我删除了表的不少数据,但是大小没变呢?
  5. ElasticSearch完结篇------京东搜索实战
  6. c++输入、输出和文件
  7. 详细解读用C语言编写的 “扫雷”程序
  8. Android RecyclerView的滚动原理
  9. android自定义GifView显示gif动画
  10. SurfaceView浅析