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=1总点数f[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;
}