YBT3.4.4 洛谷P3275 糖果_恒星的亮度

YBT3.4.4 洛谷P3275 糖果_恒星的亮度

Title

思路

建图:

1

A<=B,B<=A
A->B B->A
边权0

2

A+1<=B
A->B
边权1

3

B<=A
B->A
边权0

4

B+1<=A
B->A
边权1

5

A<=B
A->B
边权0

Tanjan缩点
拓扑DP
入度0的点f=1
f[v]=max(f[u]+w,f[v]);
w为该边边权
ans= ∑ i = 1 总 点 数 f [ i ] ∗ s [ i ] \sum _{i=1}^{总点数} f[i]*s[i] i=1f[i]s[i]

CODE

#include<iostream>
#include<cstdio>
#include<stack>
#include<queue>
using namespace std;
const long long maxn=1000010;
struct jgt{long long u,v,nxt,w;} e[2][maxn];
long long head[2][maxn],tot[2];
long long dfn[maxn],low[maxn],col[maxn],s[maxn],ins[maxn],f[maxn],cnt,len;
stack<long long>stck;
queue<long long>que;
void Tanjan(long long x)
{
	dfn[x]=low[x]=++cnt,stck.push(x);
	for(long long i=head[0][x]; i; i=e[0][i].nxt)
		if(!dfn[e[0][i].v])Tanjan(e[0][i].v),low[x]=min(low[x],low[e[0][i].v]);
		else if(!col[e[0][i].v])low[x]=min(low[x],dfn[e[0][i].v]);
	if(dfn[x]==low[x])
	{
		for(col[x]=++len,s[len]=1; stck.top()!=x; stck.top(),stck.pop())col[stck.top()]=len,s[len]++;
		stck.pop();
	}
	return;
}
void add(long long u,long long v,long long w,long long T)
{e[T][++tot[T]].u=u,e[T][tot[T]].v=v,e[T][tot[T]].w=w,e[T][tot[T]].nxt=head[T][u],head[T][u]=tot[T];return;}
int main()
{
	ios::sync_with_stdio(false);
	long long n,m,i,ans,j,w,T,A,B;
	for(cin>>n>>m,i=1; i<=m; i++)
	{
		cin>>T>>A>>B;
		switch(T)
		{
			case 1:{add(A,B,0,0),add(B,A,0,0);break;}
			case 2:{if(A==B){cout<<-1;return 0;}add(A,B,1,0);break;}
			case 3:{add(B,A,0,0);break;}
			case 4:{if(A==B){cout<<-1;return 0;}add(B,A,1,0);break;}
			case 5:{add(A,B,0,0);break;}
		}
	}
	for(i=1; i<=n; i++)if(!dfn[i])Tanjan(i);
	for(i=1; i<=tot[0]; i++)
		if(col[e[0][i].u]!=col[e[0][i].v])add(col[e[0][i].u],col[e[0][i].v],e[0][i].w,1),ins[col[e[0][i].v]]++;
		else if(e[0][i].w){cout<<"-1\n";return 0;}
	for(j=1; j<=len; j++)
		if(!ins[j])que.push(j),f[j]=1;
	for(ans=0; que.size(); que.pop())
		for(w=que.front(),ans+=f[w]*s[w],j=head[1][w]; j; j=e[1][j].nxt)
		{
			f[e[1][j].v]=max(f[w]+e[1][j].w,f[e[1][j].v]);
			if(!(--ins[e[1][j].v]))que.push(e[1][j].v);
		}
	cout<<ans<<endl;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值