UVA 11865 Stream My Contest(最小树形图)
题意:N台机器,M条有向边,总资金C,现要到搭建一个以0号机(服务器)为跟的网路,已知每条网线可以把数据从u传递到v,其带宽为d,花费为c,且d越大,传输速度越快,问能够搭建的传输速度最快的网络d值是多少?(即:在C的支持下,网络中d的最小值最大是多少?)
一开始把问题想简单了,以为网线可以随便接,其实是确定了u->v的= =
最小树形图,概念蛮好理解的,要学习的话
理论:http://hi.baidu.com/bin183/item/5d93ef69ceb541176895e682
代码标注的很详细:http://blog.csdn.net/hehedounima/article/details/9320173
其实,实质就是不断地缩点。需要注意的是选取以每个点为终点的最小边,以及重建图。
因为看人家缩点部分的代码写得略挫,于是我就写了个更挫的T^T——基于强连通缩点的。。细节在代码里已经标明
#include<cstdio>
#include<cmath>
#include<cstring>
#include<vector>
#include<queue>
#include<stack>
#include<algorithm>
#define clr(a,m) memset(a,m,sizeof(a))
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std; const int MAXN=;
const int MAXM=;
const int INF =1e9; struct Edge{
int u,v,d,c;
}; int _n,m,w;
int root,u[MAXM],v[MAXM],d[MAXM],c[MAXM]; int head[MAXN],tol; int pre[MAXN],low[MAXN],sccno[MAXN],scc_cnt,dfs_clock;
int stk[MAXN],top; bool mark[MAXN];
Edge into[MAXN]; vector<Edge>edge;
vector<int>G[MAXN]; void init()
{
edge.clear();
rep(i,,_n-)//!!写成m-1,RE的泪啊
G[i].clear();
} void add(int u,int v,int d,int c)
{
edge.push_back((Edge){u,v,d,c});
int m=edge.size();
G[u].push_back(m-);
} void build()
{
rep(i,,m-)
add(u[i],v[i],d[i],c[i]);
} void rebuild()
{
rep(i,,m-){
int v=edge[i].v;
edge[i].u=sccno[edge[i].u];//自环会在处理into[]时省略
edge[i].v=sccno[edge[i].v];
if(edge[i].u!=edge[i].v)
edge[i].c-=into[v].c;
}
root=sccno[root];//更新root、n的值
_n=scc_cnt;
} void dfs(int v)//因为into[]里是以终点v记录,所以反向缩点
{
int u;
low[v]=pre[v]=dfs_clock++;
stk[top++]=v; u=into[v].u;
if(u!=root)//!!必不可少
if(!pre[u]){
dfs(u);
low[v]=min(low[v],low[u]);
}else if(!sccno[u])
low[v]=min(low[v],pre[u]); if(low[v]==pre[v]){
scc_cnt++;
do{
u=stk[--top];
sccno[u]=scc_cnt;
}while(u!=v);
}
} int find_scc()
{
scc_cnt=dfs_clock=;
clr(pre,);
clr(sccno,); top=;
rep(i,,_n)
if(!pre[i])
dfs(i);
return scc_cnt;
} bool DMST(int lim,int n)
{
_n=n; init();
build(); int cnt=;
while()
{
clr(mark,);
rep(i,,m-){
if(edge[i].d<lim||edge[i].u==edge[i].v)//注意自环
continue;
if(!mark[edge[i].v]){
into[edge[i].v]=(Edge){edge[i].u,edge[i].v,edge[i].d,edge[i].c};
mark[edge[i].v]=true;
}else if(into[edge[i].v].c>edge[i].c)
into[edge[i].v]=(Edge){edge[i].u,edge[i].v,edge[i].d,edge[i].c};
}
into[root]=(Edge){root,root,,};//处理根 rep(i,,_n){//root的序号随缩点改变
if(i==root)
continue;
if(!mark[i]){
return false;
}
cnt+=into[i].c;
}
if(cnt>w)
return false; if(find_scc()==_n)//若不成环
return true;
else
rebuild();
}
} int main()
{
int T,n;
scanf("%d",&T);
while(T--)
{
int up=,down=INF;
scanf("%d%d%d",&n,&m,&w);
root=; rep(i,,m-){
scanf("%d%d%d%d",&u[i],&v[i],&d[i],&c[i]);
u[i]++;v[i]++;//注意scc_cnt是从1开始的,意味着所有的点都是1~n
up=max(up,d[i]);
down=min(down,d[i]);
} if(!DMST(down,n)){
printf("streaming not possible.\n");
continue;
} int l=down,r=up;
while(l<r)
{
int x=l+(r-l+)/;
if(DMST(x,n))
l=x;
else
r=x-;
}
printf("%d kbps\n",l);
}
return ;
}
/*
3
7 15 29
0 1 1 9
0 4 1 5
1 3 1 9
1 2 1 3
2 1 1 7
2 6 1 6
2 5 1 9
3 0 1 3
3 2 1 8
3 5 1 5
4 3 1 4
5 4 1 3
5 6 1 4
6 2 1 4
6 5 1 8
*/
UVA 11865 Stream My Contest(最小树形图)的更多相关文章
- UVA 11865 Stream My Contest (二分+最小树形图)
题意:给定一个网络,一个服务器,其他的是客户机,有 m 条连线,每条有一个带宽和花费(单向边),让你用不超过 c 的花费,使得 0 到 所有的机器都能到达,并且使得最小带宽最大. 析:很明显是二分题, ...
- Stream My Contest UVA - 11865(带权最小树形图+二分最小值最大化)
#include <iostream> #include <cstdio> #include <sstream> #include <cstring> ...
- UVA 11865 Stream My Contest 组网 (朱刘算法,有向生成树,树形图)
题意: 给n个点编号为0~n-1,0号点为根,给m条边(含自环,重边),每条边有个代价,也有带宽.给定c,问代价不超过c,树形图的最小带宽的最大值能达到多少? 思路: 点数才60,而带宽范围也不大,可 ...
- UVA 11183 Teen Girl Squad 最小树形图
最小树形图模板题 #include <iostream> #include <algorithm> #include <cstdio> #include <c ...
- uvalive 11865 Stream My Contest
题意: 有一个网络中心,和许多个城市,网络中心以及城市之间有若干条边,这些边有两个属性,最大带宽和修建费用. 现在要用最多不超过C的费用修建网络,使得每个城市都有网络连接,最大化最小带宽. 带宽限制是 ...
- 【UVA 11865】 Stream My Contest (二分+MDST最小树形图)
[题意] 你需要花费不超过cost元来搭建一个比赛网络.网络中有n台机器,编号0~n-1,其中机器0为服务器,其他机器为客户机.一共有m条可以使用的网线,其中第i条网线的发送端是机器ui,接收端是机器 ...
- Uva 11183 - Teen Girl Squad (最小树形图)
Problem ITeen Girl Squad Input: Standard Input Output: Standard Output You are part of a group of n ...
- UVA 6199 不定根最小树形图
首先是最小树形图的介绍. 看这个博客.最小树形图 上面介绍的很详细了,我就讲一下这道题的题意. 首先给出一些二维点坐标,这些坐标之间构成一些有向图,根据题意,假设两个点a(x1 ,y1) ,b(x2 ...
- 【二分+最小树形图】UVA11865 比赛网络
Description During 2009 and 2010 ICPC world finals, the contest was webcasted via world wide web. Se ...
随机推荐
- oracle 删除用户,表空间;循环删除表
select * from dba_tablespaces 说明:查看所有表空间 ----------------------------------------------------------- ...
- tar命令,转来等用
tar 解压缩命令 tar -c: 建立压缩档案 -x:解压 -t:查看内容 -r:向压缩归档文件末尾追加文件 -u:更新原压缩包中的文件 这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令 ...
- Leetcode#79 Word Search
原题地址 依次枚举起始点,DFS+回溯 代码: bool dfs(vector<vector<char> > &board, int r, int c, string ...
- 写一个函数,实现两个字符串的比较。即实现strcmp函数,s1=s2时返回0,s1!=s2时返回二者第一个不同字符的ASCII值。
#include<stdio.h> #include<stdlib.h> int main(){ setvbuf(stdout,NULL,_IONBF,); ],s2[]; i ...
- BitNami一键安装Redmine(转)
1. 简介 对于一个新手,如果严格按照官方文档来安装redmine,我想会“疯”掉的.有没有一种简便的方法.有滴,那就是BitNami. BitNami提供redmine的一键安装程序,简单.易用.方 ...
- Linux下SVN的一些使用方法总结
Linux下SVN的一些使用方法总结 近期的一个项目不方便 Check 到本地,需要在测试服务器上进行编写和测试,所以就研究了一下如何在 Linux 命令行下使用 SVN. 首先 svn help ...
- POJ 1060 Modular multiplication of polynomials(多项式的加减乘除,除法转化成减法来求)
题意:给出f(x),g(x),h(x)的 (最高次幂+1)的值,以及它们的各项系数,求f(x)*g(x)/h(x)的余数. 这里多项式的系数只有1或0,因为题目要求:这里多项式的加减法是将系数相加/减 ...
- H5 移动Web框架集合
http://frozenui.github.io/ 一个简洁的h5前端框架 http://weui.github.io/weui/ 腾讯出的WebUI 风格是基于微信
- 【mongoDB基础篇②】PHP-mongo扩展的编译以及使用
安装PHP-mongo扩展 安装php-mongo扩展和安装其他php扩展的步骤一样: #1.首先上http://pecl.php.net上面搜索mongo,得到下载地址 wget http://pe ...
- python 字符串格式化 输出
1. 需要输出3列,为了输出好看,需要制定每一列的宽度: ‘%6.2f’ % 1.235 # 长度为6,保留2为小数 print '{0:20} {1:<20} {1:<20}\r\n'. ...