hdu 6041 I Curse Myself
题目:
点这里OvO http://acm.hdu.edu.cn/showproblem.php?pid=6041
2017 Multi-University Training Contest - Team 1 - 1009
题解:
1.由于每条边只在一个环中,每个环必然要拿掉一条边,而这些边都是不重复的,那么最小生成树就对应的是通过求每个环中拿掉一条边,总和最大的组合对应的剩下的树(第k小生成树对应第k大组合剩下的树)。xjbdfs搜一下环,把每个环中的点放到一个集合中。
2.然后对集合排序,xjb利用优先队列 ( 要注意优先队列中的元素的数量要保持和新集合的元素个数相同,以降低时间复杂度 ) 求最大的k(如果总数没k个那就不是k个)个组合(每个集合中取一个元素的组合)
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue> using namespace std; typedef long long ll; const int N=1e4+;
const int M=2e3+;
const ll mod=(ll)pow(,); struct node{
int u,v,d;
int next;
}edge[*N]; struct NODE
{
int v,now; //value is (v), now add with (now)
friend bool operator<(NODE x,NODE y)
{
return x.v < y.v;
}
};//small to big priority_queue<NODE> Q;
int num;
int head[N];
int n,m,k;
ll ans;
int snum;
int stk[N],lstk;
bool instk[M];
vector<int> s[N];
int val[M][M];
vector<int> f,tmpf;
ll sum_of_edge;
ll du[M]; bool cmp(int a,int b)
{
return a>b;
} void addedge(int u,int v,int d)
{
edge[num].u=u;
edge[num].v=v;
edge[num].d=d;
edge[num].next=head[u];
head[u]=num++;
} void init()
{
num=; //记得初始化
memset (head,-,sizeof(head));
memset(du,,sizeof(du));
snum=;
lstk=;
memset(instk,,(n+)*sizeof(bool));
for(int i=;i<=n;i++)
s[i].clear();
ans=;
sum_of_edge=;
} void dfs(int rt,int fa)
{
int v;
if(instk[rt])
{
snum++;
int sav=rt;
int sav_lstk=lstk;
while(stk[lstk]!=rt)
{
s[snum].push_back(val[sav][stk[lstk]]);
sav=stk[lstk--];
}
s[snum].push_back(val[sav][stk[lstk]]);
lstk=sav_lstk;
return ;
}
instk[rt]=;
stk[++lstk]=rt;
for(int i=head[rt];i!=-;i=edge[i].next)
{
v=edge[i].v;
if(v==fa || du[v]==) continue;
du[rt]--; du[v]--;
dfs(v,rt);
}
instk[rt]=;
lstk--;
} void merge()
{
NODE q;
int i,j,cnt;
f.clear();
if(snum==)
{
f.push_back();
return ;
}
for(int i=;i<s[].size();i++)
f.push_back(s[][i]);
for(int i=;i<=snum;i++)
{
cnt=f.size()*s[i].size();
if(cnt>k) cnt=k;
while(!Q.empty())
Q.pop();
for(j=;j<s[i].size();j++)
{
q.v=s[i][j]+f[];
q.now=;
Q.push(q);
}
tmpf.clear();
while(cnt--)
{
q=Q.top();
Q.pop();
tmpf.push_back(q.v);
if(q.now!=f.size()-)
{
q.v-=f[q.now];
q.now++;
q.v+=f[q.now];
Q.push(q);
}
}
swap(f,tmpf);
}
// cout<<"check merge\n";
// for(int i=0;i<f.size();i++)
// printf("%d ",f[i]);
// printf("\n");
// printf("end of check of merge\n");
} void solve()
{
dfs(,-);
for(int i=;i<=snum;i++)
sort(s[i].begin(),s[i].end(),cmp);
// printf("check s\n");
// for(int i=1;i<=snum;i++)
// {
// for(int j=0;j<s[i].size();j++)
// printf("%d",s[i][j]);
// printf("\n");
// }
// printf("end of check of s\n");
merge();
} int main()
{
int cas=,a,b,c;
while(scanf("%d%d",&n,&m)!=EOF)
{
init();
for(int i=;i<=m;i++)
{
scanf("%d%d%d",&a,&b,&c);
addedge(a,b,c);
addedge(b,a,c);
du[a]++; du[b]++;
val[a][b]=val[b][a]=c;
sum_of_edge+=c;
}
scanf("%d",&k);
solve();
for(int i=;i<f.size();i++)
ans=(ans+1ll*(i+)*(sum_of_edge-f[i])%mod)%mod;
printf("Case #%d: %lld\n",++cas,ans%mod);
}
return ;
}
hdu 6041 I Curse Myself的更多相关文章
- HDU 6041 - I Curse Myself | 2017 Multi-University Training Contest 1
和题解大致相同的思路 /* HDU 6041 - I Curse Myself [ 图论,找环,最大k和 ] | 2017 Multi-University Training Contest 1 题意 ...
- HDU 6041.I Curse Myself 无向仙人掌图
I Curse Myself Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) ...
- HDU 6041 I Curse Myself(二分+搜索)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=6041 [题目大意] 给出一个仙人掌图,求第k小生成树 [题解] 首先找到仙人掌图上的环,现在的问题 ...
- hdu 6041 I Curse Myself 无向图找环+优先队列
I Curse Myself Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) ...
- HDU 6041 I Curse Myself(点双联通加集合合并求前K大) 2017多校第一场
题意: 给出一个仙人掌图,然后求他的前K小生成树. 思路: 先给出官方题解 由于图是一个仙人掌,所以显然对于图上的每一个环都需要从环上取出一条边删掉.所以问题就变为有 M 个集合,每个集合里面都有一堆 ...
- HDU 6041 I Curse Myself ——(仙人掌图,tarjan,转化)
题解见这个博客:http://blog.csdn.net/ME495/article/details/76165039. 复杂度不太会算..这个经典问题的解法需要注意,维护队列里面只有k个元素即可.另 ...
- HDU - 6041:I Curse Myself(Tarjan求环&K路归并)
There is a connected undirected graph with weights on its edges. It is guaranteed that each edge app ...
- HDU 2520 我是菜鸟,我怕谁
我是菜鸟,我怕谁 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Su ...
- HDU 5433 Xiao Ming climbing 动态规划
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5433 Xiao Ming climbing Time Limit: 2000/1000 MS (Ja ...
随机推荐
- 灾备系统 RTO与RPO
出处: https://blog.51cto.com/se7en/1085442 http://www.iso27001.org.cn/fuwu/it/iso22301/show_511.html h ...
- 22 Years of KDE
22 Years of KDEhttps://timeline.kde.org/ http://www.kdedevelopers.org/
- Java EE javax.servlet中的ServletContext接口
ServletContext接口 public interface ServletContext (https://docs.oracle.com/javaee/7/api/javax/servlet ...
- js跨域原理及解决方案
方法一:jsonp函数 在HTML DOM中,Script标签是可以跨域访问服务器上的数据的.因此,可以指定script的src属性为跨域的url,基于script标签实现跨域.script标签本身就 ...
- url请求
--[[local g = require 'library.global'--__ml_ss = mlc.prefix.ml_psession..tostring(os.time());local ...
- MFC 下调试 出现 warning : fail to load indicator string 0x0069
MFC 下调试 出现 warning : fail to load indicator string 0x0069 就是程序状态栏每一个标识列中至少有一个值没有初始值 或初始值为空 导致程序没有获取到 ...
- Advanced Installer 不弹出预安装的软件的窗口
需求:当他电脑上没有sql server client 的时候,或没有localdb的时候,那么安装包会弹出窗口,让他选择 一个组件 一个组件的安装 太麻烦. 有没有办法,打开安装包就安装 安装的过程 ...
- Centos7:MyCat安装,配置及使用
解压缩 使用,默认端口8066 ./mycat start //启动 ./mycat stop //停止 ./mycat restart //重启
- Python中文分词组件 jieba
jieba "结巴"中文分词:做最好的Python中文分词组件 "Jieba" Feature 支持三种分词模式: 精确模式,试图将句子最精确地切开,适合文本分 ...
- java反射浅谈 part1--反射机制的定义,作用,原理
一.定义 在运行过程中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:还可以通过反射创建对象,这种动态获取的信息以及动态调用对象的方法的功能称为 ...