按紫书来
注意这道题的题目给了很大的方便,就相当于验证k是不是答案,不是的话就是k+1

#include<iostream>
#include<string>
#include<cstring>
#include<sstream>
#include<vector>
#include<algorithm>
using namespace std; const int maxn = + ;
const int INF = ; struct Edge {
int u, v, d; // d=1 means u->v, d=2 means v->u, d=0 means u-v
Edge(int u=, int v=, int d=):u(u),v(v),d(d){}
}; vector<Edge> edges[maxn];
int n, root, maxlen, f[maxn], g[maxn], have_father[maxn]; // maximal length of a DIRECTED path starting from u
int dfs(int u) {
int ans = ;
for(int i = ; i < edges[u].size(); i++) {
int v = edges[u][i].v;
if(edges[u][i].d == )
ans = max(ans, dfs(v)+);
}
return ans;
} bool read_data() {
bool have_data = false;
int a, b;
n = ;
for(int i = ; i < maxn; i++) edges[i].clear();
memset(have_father, , sizeof(have_father)); while(cin >> a && a){
string str;
have_data = true;
if(a > n) n = a;
while(cin >> str && str != ""){ //一组数据
int len = str.length();
char dir = str[len-];
if(dir == 'd' || dir == 'u') str = str.substr(, len-);
stringstream ss(str);
ss >> b; // b is a's son
if(b > n) n = b;
have_father[b] = ;
if(dir == 'd'){
edges[a].push_back(Edge(a, b, )); // forward
edges[b].push_back(Edge(b, a, )); // backward
}else if(dir == 'u'){
edges[a].push_back(Edge(a, b, ));
edges[b].push_back(Edge(b, a, ));
}else{
edges[a].push_back(Edge(a, b, )); // it's a rooted tree, so we don't store edge to father
}
}
}
if(have_data) {
for(int i = ; i <= n; i++)
if(!have_father[i]) { root = i; break; } //找一个root //if(!have_father[i] && !edges[i].empty())
}
return have_data;
} struct UndirectedSon {
int w, f, g;
UndirectedSon(int w=, int f=, int g=):w(w),f(f),g(g){}
}; bool cmp_f(const UndirectedSon& w1, const UndirectedSon& w2) {
return w1.f < w2.f;
} bool cmp_g(const UndirectedSon& w1, const UndirectedSon& w2) {
return w1.g < w2.g;
} // calculate f[i] and g[i]
// return true iff f[i] < INF
// f[i] is the minimal length of the longest "->u" path if all subtree paths have length <= maxlen
// g[i] is the minimal length of the longest "u->" path if all subtree paths have length <= maxlen
// f[i] = g[i] = INF if "all subtree paths have length <= maxlen" cannot be satisfied
bool dp(int i, int fa) {
if(edges[i].empty()) {
f[i] = g[i] = ;
return true;
}
vector<UndirectedSon> sons;
int f0 = , g0 = ; // f'[i] and g'[i] for directed sons // let f'[i] = max{f[w] | w->i}+1, g'[i] = max{g[w] | i->w}+1
// then we should change some undirected edges to ->u or u-> edges so that f'[i]+g'[i] <= maxlen
// then f[i] is the minimal f'[i] under this condition, and g[i] is the minimal g'[i]
for(int k = ; k < edges[i].size(); k++) {
int w = edges[i][k].v;
if(w == fa) continue;
dp(w, i);
int d = edges[i][k].d;
if(d == ) sons.push_back(UndirectedSon(w, f[w], g[w]));
else if(d == ) g0 = max(g0, g[w]+);
else f0 = max(f0, f[w]+);
}
// If there is no undirected edges, we're done
if(sons.empty()) {
f[i] = f0; g[i] = g0;
if(f[i] + g[i] > maxlen) { f[i] = g[i] = INF; }
return f[i] < INF;
} f[i] = g[i] = INF; // to calculate f[i], we sort f[w] of undirected sons in increasing order and make first p edges to w->i
// then we calculate f'[i] and g'[i], check for f'[i]+g'[i] <= maxlen and update answer
int s = sons.size(); sort(sons.begin(), sons.end(), cmp_f);
int maxg[maxn]; // maxg[i] is max{sons[i].g, sons[i+1].g, ...} //按f从小到大排
maxg[s-] = sons[s-].g;
for(int k = s-; k >= ; k--)
maxg[k] = max(sons[k].g, maxg[k+]); //记录k之后最长的g[w],用于排序
for(int p = ; p <= sons.size(); p++) {
int ff = f0, gg = g0; //原来最长的有向边
if(p > ) ff = max(ff, sons[p-].f+);
if(p < sons.size()) gg = max(gg, maxg[p]+);
if(ff + gg <= maxlen) f[i] = min(f[i], ff);
} // g[i] is similar
sort(sons.begin(), sons.end(), cmp_g);
int maxf[maxn]; // maxf[i] is max{sons[i].f, sons[i+1].f, ...}
maxf[s-] = sons[s-].f;
for(int k = s-; k >= ; k--)
maxf[k] = max(sons[k].f, maxf[k+]);
for(int p = ; p <= sons.size(); p++) {
int ff = f0, gg = g0;
if(p > ) gg = max(gg, sons[p-].g+); //比p小的f(w)变成w->i,不会让f[i]变大,但可能让g[i]变小
if(p < sons.size()) ff = max(ff, maxf[p]+);
if(ff + gg <= maxlen) g[i] = min(g[i], gg);
} return f[i] < INF;
} int main() {
while(read_data()) {
maxlen = ;
for(int i = ; i <= n; i++) maxlen = max(maxlen, dfs(i));
// Note: the problem asks for the number of nodes in path, but all the "lengths" above mean "number of edges"
if(dp(root, -)) cout << maxlen+ << "\n";
else cout << maxlen+ << "\n";
}
return ;
}

uva1380 A Scheduling Problem的更多相关文章

  1. 【暑假】[深入动态规划]UVa 1380 A Scheduling Problem

     UVa 1380 A Scheduling Problem 题目: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=41557 ...

  2. 【UVA 1380】 A Scheduling Problem (树形DP)

    A Scheduling Problem   Description There is a set of jobs, say x1, x2,..., xn <tex2html_verbatim_ ...

  3. UVA 1380 A Scheduling Problem

    题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...

  4. [UVALive 3683] A Scheduling Problem

    图片加载可能有点慢,请跳过题面先看题解,谢谢 题目给出了一个信息:答案是有向边最长路 \(k\) 的值或者是 \(k+1\) 的值 那么题目就变成了:求是否有一种给无向边定向的方案,使得在以有向边最长 ...

  5. 题解 AT4170 【[ABC103A] Task Scheduling Problem】

    翻译 有 \(3\) 个正整数 \(a\).\(b\).\(c\),请你输出这 \(3\) 个数中的最大值 \(-\) 最小值的差. 分析 求最大值 \(-\) 最小值的差,我们自然可以使用 for ...

  6. POJ 1325 Machine Schedule——S.B.S.

    Machine Schedule Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 13731   Accepted: 5873 ...

  7. *HDU1150 二分图

    Machine Schedule Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  8. Dynamic Programming

    We began our study of algorithmic techniques with greedy algorithms, which in some sense form the mo ...

  9. poj 1325 Machine Schedule

    Time Limit: 1000 MS Memory Limit: 10000 KB 64-bit integer IO format: %I64d , %I64u   Java class name ...

随机推荐

  1. web.xml配置之<context-param>

    <context-param>的作用和用法: 1.<context-param>配置是是一组键值对,比如: <context-param>        <p ...

  2. AndroidStudio修改主题外观和字体大小

    修改主题外观 File --> Settings --> Appearance & Behavior --> Appearance 右边 Theme 修改编辑器的字体大小 F ...

  3. 网络爬虫之Selenium模块和Xpath表达式+Lxml解析库的使用

    实际生产环境下,我们一般使用lxml的xpath来解析出我们想要的数据,本篇博客将重点整理Selenium和Xpath表达式,关于CSS选择器,将另外再整理一篇! 一.介绍: selenium最初是一 ...

  4. HDU 5883 The Best Path (欧拉路或者欧拉回路)

    题意: n 个点 m 条无向边的图,找一个欧拉通路/回路使得这个路径所有结点的异或值最大. 析:由欧拉路性质,奇度点数量为0或2.一个节点被进一次出一次,度减2,产生一次贡献,因此节点 i 的贡献为 ...

  5. 所读STL文章摘要集结

    在网上看了一些STL相关文章,这里将它们的摘要进行集结,方便以后查找. 1.黄常标,林俊义,江开勇.快速成形中STL文件拓扑信息的快速建立.2004 摘要:在分析现有建立拓扑信息方法的基础上,提出基于 ...

  6. 鉴于spfa基础上的差分约束算法

    怎么搞?        1. 如果要求最大值      想办法把每个不等式变为标准x-y<=k的形式,然后建立一条从y到x权值为k的边,变得时候注意x-y<k =>x-y<=k ...

  7. 基于FBX SDK的FBX模型解析与加载 -(二)

    http://blog.csdn.net/bugrunner/article/details/7211515 5. 加载材质 Material是一个模型渲染时必不可少的部分,当然,这些信息也被存到了F ...

  8. 黑客攻防技术宝典web实战篇:查找源代码中的漏洞习题

    猫宁!!! 参考链接:http://www.ituring.com.cn/book/885 随书答案. 1. 列出 3 种可在源代码中找到明确签名的常见漏洞. (a) 跨站点脚本(b) SQL 注入( ...

  9. TC学习总结

    带宽管理: TC中规定描述带宽: mbps = 1024 kbps = 1024 * 1024 bps => byte/s mbit = 1024 kbit => kilo bit/s m ...

  10. Python 教程资源

    1.廖雪峰的官方网站 http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001386 ...