使用SCC缩点之后跑树上DP为什么过不了。。
  • 板块P2648 赚钱
  • 楼主guanjinquan
  • 当前回复6
  • 已保存回复6
  • 发布时间2021/5/2 09:54
  • 上次更新2023/11/4 23:51:54
查看原帖
使用SCC缩点之后跑树上DP为什么过不了。。
385781
guanjinquan楼主2021/5/2 09:54
#include<bits/stdc++.h>
#define ll long long
#define lld long double
#define uint unsigned int
#define ull unsigned long long
#define fi first
#define se second
#define emp(a)  emplace_back(a)
#define iter(c)   __typeof((c).begin())
#define ios ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define PII pair<int,int>
#define PLL pair<ll,ll>
#define me(x,y) memset((x),(y),sizeof(x))
#define mp make_pair
using namespace std;
template<class T,class F>inline F max(T a,F b){return (a>b)?a:b;}
template<class T,class F>inline F min(T a,F b){return (a>b)?b:a;}
template<typename T>
inline void read(T&res){ //
    ll x=0,f=1;char ch;
    ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    res = x*f;
}
template<typename T,typename...Args>inline
void read(T&t,Args&...a){read(t);read(a...);}

const ll maxn = 2e4+11,inf = 0x3f3f3f3f,mod = 998244353;
int n,c,m,q,scc,du[maxn],id[maxn],dfn[maxn],low[maxn],top;
ll ans,mx[maxn];
stack<int>s;
bool ins[maxn];
vector<PII>e[maxn];
vector<array<int,4>>te[maxn];
vector<int>p[maxn];

inline void dfs(int x){
	ins[x]=dfn[x]=low[x]=++top;
	s.push(x);
	for(auto [v,val] : e[x]){
		if(!dfn[v]){
			dfs(v);
			low[x] = min(low[v],low[x]);
		}
		else if(ins[v])
			low[x] = min(low[x],dfn[v]);
	}
	if(low[x]==dfn[x]){
		scc++;
		int v = 0;
		while(v!=x){
			v = s.top();s.pop();
			ins[v] = 0;
			id[v] = scc;
			p[scc].emp(v);
		}
	}
}

inline bool ok(int x,int dis){
	if(ins[x]&&dis>0)return 0;
	else if(ins[x]&&dis<=0)return 1;
	ins[x] = 1;
	for(auto [v,val] : e[x])
		if(id[v]==id[x]&&!ok(v,dis+c-val))return 0;
	ins[x] = 0;
	return 1;
}

inline void calc(int x){
	for(auto [v,val] : e[x]){
		if(id[x]==id[v]&&mx[v]<mx[x]+c-val){
			mx[v] = mx[x]+c-val;
			calc(v);
		}
	}
}

inline void bfs(){
	queue<int>q;
	for(int i = 1;i <= scc;i++)
		if(du[i]==0)q.push(i);
	for(int i = 1;i <= n;i++)mx[i]=c;
	if(q.empty())q.push(1);
	while(!q.empty()){
		int x = q.front();q.pop();
		for(auto [i,a,b,val] : te[x]){
			du[i]--;
			mx[b] = max(mx[b],mx[a]-val+c);
			if(du[i]==0){
				q.push(i);
				for(int v:p[i])
					calc(v);
			}
		}
	}
	for(int i = 1;i <= n;i++)
		ans = max(mx[i],ans);
}

inline void solve()
{
	read(c,m,n,q);
	for(int i = 1,t1,t2;i <= m;i++){
		read(t1,t2);
		e[t1].emp(mp(t2,0));
	}
	for(int i = 1,t1,t2,t3;i <= q;i++){
		read(t1,t2,t3);
		e[t1].emp(mp(t2,t3));
	}
	for(int i = 1;i <= n;i++){
		if(!dfn[i])dfs(i);
	}
	for(int i = 1;i <= scc;i++){
		if(!ok(p[i][0],0)){
			puts("orz");
			return ;
		}
	}
	for(int i = 1;i <= n;i++){
		int x = i;
		for(auto [v,val]:e[x]){
			if(id[v]==id[x])continue;
			te[id[x]].push_back({id[v],x,v,val});
			du[id[v]]++;
		}
	}
	bfs();
	printf("%lld\n",ans);
}

int main()
{
	//freopen("H5.in","r",stdin);
	//freopen("PH5.out","w",stdout);
    int TEST = 1;
    //cin>>TEST;
    //~scanf("%d",&TEST);
    //getchar();
    while(TEST--)
        solve();
}
2021/5/2 09:54
加载中...