洛谷P1455搭配購買
阿新 • • 發佈:2018-10-31
傳送門啦
這是強連通分量與揹包的例題
需要注意的就是價值和價格兩個陣列不要打反了。。
另外 這是雙向圖!!!
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 1e4 + 4; const int maxm = 5005; int n,m,mon; int c[maxn],w[maxn],u,v; int C[maxn],W[maxn],f[maxn]; int head[maxn],tot; int dfn[maxn],low[maxn],ind; int num[maxn],belong[maxn],cnt,stack[maxn],top; bool ins[maxn]; struct Edge{ int to,next,from; }edge[maxm << 1]; void add(int u,int v){ edge[++tot].from = u; edge[tot].to = v; edge[tot].next = head[u]; head[u] = tot; } int read(){ char ch = getchar(); int f = 1 , x = 0; while(ch > '9' || ch < '0'){ if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ x = x * 10 + ch - '0'; ch = getchar(); } return x * f; } void tarjan(int x){ dfn[x] = low[x] = ++ind; stack[++top] = x; ins[x] = true; for(int i=head[x];i;i=edge[i].next){ int v = edge[i].to; if(!dfn[v]){ tarjan(v); low[x] = min(low[x] , low[v]); } else if(ins[v]) low[x] = min(low[x] , dfn[v]); } int k = 0; if(dfn[x] == low[x]){ ++cnt; do{ k = stack[top]; num[cnt]++; top--; ins[k] = false; belong[k] = cnt; C[cnt] += c[k]; W[cnt] += w[k]; } while(k != x); } } int main(){ n = read(); m = read(); mon = read(); for(int i=1;i<=n;i++){ c[i] = read(); w[i] = read(); } for(int i=1;i<=m;i++){ u = read(); v = read(); add(u,v); add(v,u); } for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i); for(int i=1;i<=cnt;i++) for(int j=mon;j>=C[i];j--) f[j] = max(f[j] , f[j - C[i]] + W[i]); printf("%d",f[mon]); return 0; }