hack数据全wa求助
  • 板块P1453 城市环路
  • 楼主wyw666
  • 当前回复0
  • 已保存回复0
  • 发布时间2021/8/6 17:06
  • 上次更新2023/11/4 11:48:23
查看原帖
hack数据全wa求助
114368
wyw666楼主2021/8/6 17:06

RT,比较暴力的用了tarjan的板子判环然后跑了一遍dp,部分变量及流程已经加上注释。

#include<bits/stdc++.h>
#define N 1000001
using namespace std;
using ll=long long;
struct edge{
	int to,next;
};
vector<edge> E;
int head[N];
void insert(int u,int v){
	E.push_back({v,head[u]});
	head[u]=E.size()-1;
}
int dfn[N],low[N],scc[N],scc_size[N],scc_count,now;
bool in_stack[N];
stack<int> s;
void add_to_scc(){
	scc[s.top()]=scc_count;
	scc_size[scc_count]++;
	in_stack[s.top()]=0;
	s.pop();
}
void tarjan(int u,int f){
	dfn[u]=low[u]=++now;
	in_stack[u]=1;
	s.push(u);
	for(int i=head[u];~i;i=E[i].next){
		int v=E[i].to;
		if(v==f)continue;
		if(!dfn[v]){
			tarjan(v,u);
			low[u]=min(low[u],low[v]);
		}
		else if(in_stack[v]) low[u]=min(low[u],dfn[v]);
	}
	if(dfn[u]==low[u]){
		++scc_count;
		while(s.top()!=u)add_to_scc();
		add_to_scc();
	}
}
int n,cnt,tscc;//tscc:环所在的scc编号 
//p1 p2分别为取/不取环上的某点时,该点及该点的子树能得到的人流最大值 
ll p[N],p1[N],p2[N],dp[N][2],ans;
double k;
//dfs计算p1和 p2 
ll calc(int x,int fa,bool limit){
	ll res0=0,res1=p[x];
	for(int i=head[x];~i;i=E[i].next){
		int v=E[i].to;
		if(v==fa||scc[v]==tscc)continue;
		res0+=calc(v,x,0);
		if(!limit)res1+=calc(v,x,1);
	}
	if(limit)return res0;
	return max(res0,res1);
}
int main(){
	memset(head,-1,sizeof head);
	cin>>n;
	for(int i=1;i<=n;i++)cin>>p[i];
	for(int i=1,u,v;i<=n;i++){
		cin>>u>>v;
		insert(u+1,v+1);
		insert(v+1,u+1);
	}
	cin>>k;
	
	//----tarjan--------------------------------
	
	tarjan(1,1);
	//遍历取tscc 
	for(int i=1;i<=scc_count;i++){
		if(scc_size[i]>1){
			tscc=i;
			break;
		}
	}
	for(int i=1;i<=n;i++){
		if(scc[i]==tscc){
			cnt++;
			p1[i]=calc(i,i,0);
			p2[i]=calc(i,i,1);
		}
	}
	
	
	//----dp-------------------------------
	
	//1取 cnt不取 
	dp[1][1]=p1[1];
	dp[1][0]=-1e17;
	for(int i=2;i<=cnt;i++){
		dp[i][0]=max(dp[i-1][0],dp[i-1][1])+p2[i];
		dp[i][1]=dp[i-1][0]+p1[i];
	} 
	ans=dp[cnt][0];
	//1不取
	dp[1][1]=-1e17;
	dp[1][0]=p2[1];
	for(int i=2;i<=cnt;i++){
		dp[i][0]=max(dp[i-1][0],dp[i-1][1])+p2[i];
		dp[i][1]=dp[i-1][0]+p1[i];
	} 
	ans=max(ans,max(dp[cnt][0],dp[cnt][1]));
	printf("%.1lf\n",static_cast<double>(ans)*k);
	return 0;
}

目前看了题解区之后用更为简便的方法A了,但是自己的代码看了一下午都没找出错来,救救孩子吧QWQ

2021/8/6 17:06
加载中...