HOJ 13415 Website Tour(强连通缩点+多重背包dp)
来源:互联网 发布:淘宝商城童装毛衣女孩 编辑:程序博客网 时间:2024/06/03 23:07
题意:每个网站有个广告,看这个广告要花t的时间,能得p的分,最多只能看s次,然后给一些网站以及它所能到达的网站,从一个网站到另一个是不花时间的,但是不能停在同一个网站连续不停的看。现在有T的时间,起点任意,问最大得分。
做法:由于都是有向边,所以我们可以把强连通分量缩点了,这其中的点都可以互相到达,再把这些缩后的点给拓扑排序,就是个DAG了,我们就可以dp了,在这个连通分量的点里面就是多重背包了,可以用二进制分解的办法做到每个点Tlogk的复杂度。然后再去更新它之后的点即可。总复杂度o(n*T*logk+m)。
AC代码:
#pragma comment(linker, "/STACK:102400000,102400000")#include<cstdio>#include<ctype.h>#include<algorithm>#include<iostream>#include<cstring>#include<vector>#include<cstdlib>#include<stack>#include<queue>#include<set>#include<map>#include<cmath>#include<ctime>#include<string.h>#include<string>#include<sstream>#include<bitset>using namespace std;#define ll __int64#define ull unsigned __int64#define eps 1e-8#define NMAX 1000000000#define MOD (1<<30)#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1#define PI acos(-1)template<class T>inline void scan_d(T &ret){ char c; int flag = 0; ret=0; while(((c=getchar())<'0'||c>'9')&&c!='-'); if(c == '-') { flag = 1; c = getchar(); } while(c>='0'&&c<='9') ret=ret*10+(c-'0'),c=getchar(); if(flag) ret = -ret;}const int maxn = 100+10;const int maxm = 1000+10;struct Edge{ int v,next;}e[2][maxm];int head[2][maxn], ecnt[2];void add_edge(int u, int v, int d){ e[d][ecnt[d]].v = v; e[d][ecnt[d]].next = head[d][u]; head[d][u] = ecnt[d]++;}struct node{ int p,t,k; node(){} node(int _p, int _t, int _k):p(_p),t(_t),k(_k){}}no[maxn];bool zi[maxn];int pre[maxn], lowlink[maxn], sccno[maxn], dfs_clock, scc_cnt, tp;int S[maxn];void dfs(int u){ pre[u] = lowlink[u] = ++dfs_clock; S[++tp] = u; for(int i = head[0][u]; ~i; i = e[0][i].next) { int v = e[0][i].v; if(!pre[v]) { dfs(v); lowlink[u] = min(lowlink[u],lowlink[v]); } else if(!sccno[v]) lowlink[u] = min(lowlink[u],pre[v]); } if(lowlink[u] == pre[u]) { scc_cnt++; while(1) { int x = S[tp]; tp--; sccno[x] = scc_cnt; if(x == u) break; } }}void find_scc(int n){ tp = -1; dfs_clock = scc_cnt = 0; memset(sccno,0,sizeof(sccno)); memset(pre,0,sizeof(pre)); for(int i = 1; i <= n; i++) if(!pre[i]) dfs(i);}vector<int>vec[105];int Em[maxm][2];bool bian[maxn][maxn];int in[maxn],top[maxn];void topo(int n){ queue<int>q; for(int i = 1; i <= n; i++) if(in[i] == 0) q.push(i); int k = 1; while(!q.empty()) { int x = q.front(); q.pop(); top[k++] = x; for(int i = head[1][x]; ~i ; i = e[1][i].next) { int v = e[1][i].v; in[v]--; if(in[v] == 0) q.push(v); } }}int dp[maxn][10000+10];node ha[maxn];int main(){#ifdef GLQ freopen("input.txt","r",stdin);// freopen("o.txt","w",stdout);#endif int n,m,T; while(~scanf("%d%d%d",&n,&m,&T) && n+m+T) { memset(head,-1,sizeof(head)); memset(ecnt,0,sizeof(ecnt)); memset(zi,0,sizeof(zi)); for(int i = 1; i <= n; i++) scanf("%d%d%d",&no[i].p,&no[i].t,&no[i].k); for(int i = 1; i <= m; i++) { int u,v; scanf("%d%d",&u,&v); if(u == v) { zi[u] = 1; Em[i][0] = -1; } else { Em[i][0] = u; Em[i][1] = v; add_edge(u,v,0); } } find_scc(n); for(int i = 1; i <= scc_cnt; i++) vec[i].clear(); for(int i = 1; i <= n; i++) { vec[sccno[i]].push_back(i); } for(int i = 1; i <= scc_cnt; i++) if(vec[i].size() == 1 && zi[vec[i][0]] == 0) no[vec[i][0]].k = 1; memset(bian,0,sizeof(bian)); memset(in,0,sizeof(in)); for(int i = 1; i <= m; i++) if(Em[i][0] != -1) { int u = sccno[Em[i][0]], v = sccno[Em[i][1]];// cout<<u<<" "<<v<<endl; if(u != v && bian[u][v] == 0) { bian[u][v] = 1; in[v]++; add_edge(u,v,1); } } topo(scc_cnt); for(int i = 1; i <= scc_cnt; i++) for(int j = 0; j <= T; j++) dp[i][j] = 0; for(int i = 1; i <= scc_cnt; i++) { int pos = top[i]; int sz = vec[pos].size(); for(int j = 0; j < sz; j++) { int id = vec[pos][j]; if(no[id].k*no[id].t >= T) { for(int v = no[id].t; v <= T; v++) dp[pos][v] = max(dp[pos][v],dp[pos][v-no[id].t]+no[id].p); continue; } int cnt = 0; while((1<<cnt+1)-1 < no[id].k) { ha[cnt] = node((1<<cnt)*no[id].p, (1<<cnt)*no[id].t, (1<<cnt)); cnt++; } int tt = no[id].k-(1<<cnt)+1; ha[cnt++] = node(tt*no[id].p, tt*no[id].t, tt); for(int k = 0; k < cnt; k++) { for(int v = T; v >= ha[k].t; v--) dp[pos][v] = max(dp[pos][v],dp[pos][v-ha[k].t]+ha[k].p); } } for(int j = head[1][pos]; ~j; j = e[1][j].next) { int v = e[1][j].v; for(int val = 0; val <= T; val++) dp[v][val] = max(dp[v][val],dp[pos][val]); } } int ans = 0; for(int i = 1; i <= scc_cnt; i++) ans = max(ans,dp[i][T]); printf("%d\n",ans); } return 0;}
0 0
- HOJ 13415 Website Tour(强连通缩点+多重背包dp)
- 强连通缩点
- 强连通缩点
- poj 3160(强连通缩点 + dp)
- 【UVa】11324 The Largest Clique 强连通缩点+DP
- UVA 11324 The Largest Clique 强连通缩点+DP
- HAOI2010软件安装--强连通缩点+树型dp
- poj 3160 (强连通缩点&简单dp)
- HDU2767 强连通缩点
- poj1236强连通缩点
- Semiconnected--强连通缩点
- 强连通缩点 hdu3072
- hdu 2767 强连通缩点
- hdu 1827 强连通缩点
- HDU 3639 强连通缩点优化
- 【强连通缩点】Popular Cows POJ2186
- hdu 3072 (强连通缩点)
- hdu 3639 (强连通缩点+搜索)
- HDU 5399(Too Simple-判定映射)
- 每天进步一点点——Linux中的文件描述符与打开文件之间的关系
- OL记载Arcgis Server切片
- Linux系统C语言操作环境变量的函数
- Round A APAC Test 2016 Problem A. Googol String
- HOJ 13415 Website Tour(强连通缩点+多重背包dp)
- Nginx从入门到精通
- hdu 4135,数学-容斥
- 关于更佳学术搜索及Android SDK更新问题
- Core Data 的简单使用
- 二叉树前序、中序、后序遍历相互求法
- javascript设计模式之工厂(Factory)模式
- Unix/Linux的内存管理
- 在macbook air配置android开发环境[eclipse篇]