80pts代码如下:
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,k;
struct edge{int v,w;};
vector<edge> G1[N],G2[N];
int low[N],dfn[N],scc[N],siz[N],dfscnt=0,scccnt=0;
bool inst[N];
stack<int> s;
int in[N];
void Tarjan(int u)
{
low[u]=dfn[u]=++dfscnt;
inst[u]=1;
s.push(u);
for (edge e:G1[u])
{
int v=e.v,w=e.w;
if (w==1) continue;
if (!dfn[v])
{
Tarjan(v);
low[u]=min(low[u],low[v]);
}
else if (inst[v]) low[u]=min(low[u],dfn[v]);
}
if (dfn[u]==low[u])
{
scccnt++;
while (s.top()!=u)
{
int node=s.top();
inst[node]=0;
scc[node]=scccnt;
s.pop();
siz[scccnt]++;
}
s.pop();
scc[u]=scccnt;
inst[u]=0;
siz[scccnt]++;
}
}
void build()
{
for (int u=1;u<=n;u++)
{
for (edge e:G1[u])
{
int v=e.v,w=e.w;
if (scc[u]!=scc[v])
{
G2[scc[u]].push_back({scc[v],w});
in[scc[v]]++;
}
}
}
}
queue<int> q;
int dp[N];
bool vis[N],flg=1;
void Topo()
{
memset(dp,0,sizeof(dp));
memset(vis,0,sizeof(vis));
for (int i=1;i<=scccnt;i++)
{
if (in[i]==0)
{
dp[i]=1;
q.push(i);
}
}
int cnt=0;
while (!q.empty())
{
int u=q.front();
q.pop();
vis[u]=1;
cnt++;
for (edge e:G2[u])
{
int v=e.v,w=e.w;
in[v]--;
dp[v]=max(dp[v],dp[u]+w);
if (!in[v]&&(!vis[v])) q.push(v);
}
}
if (cnt<scccnt) flg=0;
}
int main()
{
scanf("%d%d",&n,&k);
int u,v,w;
for (int i=1;i<=k;i++)
{
scanf("%d%d%d",&w,&u,&v);
if (w==1)
{
G1[u].push_back({v,0});
G1[v].push_back({u,0});
}
if (w==2) G1[u].push_back({v,1});
if (w==3) G1[v].push_back({u,0});
if (w==4) G1[v].push_back({u,1});
if (w==5) G1[u].push_back({v,0});
}
for (int i=1;i<=n;i++)
{
if (!dfn[i]) Tarjan(i);
}
build();
Topo();
if (!flg) cout<<-1<<endl;
else
{
long long ans=0;
for (int i=1;i<=scccnt;i++) ans+=((long long)dp[i]*siz[i]);
printf("%lld\n",ans);
}
return 0;
}
AC代码如下:
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,k;
struct edge{int v,w;};
vector<edge> G1[N],G2[N];
int low[N],dfn[N],scc[N],siz[N],dfscnt=0,scccnt=0;
bool inst[N];
stack<int> s;
int in[N];
void Tarjan(int u)
{
low[u]=dfn[u]=++dfscnt;
inst[u]=1;
s.push(u);
for (edge e:G1[u])
{
int v=e.v;
if (!dfn[v])
{
Tarjan(v);
low[u]=min(low[u],low[v]);
}
else if (inst[v]) low[u]=min(low[u],dfn[v]);
}
if (dfn[u]==low[u])
{
scccnt++;
while (s.top()!=u)
{
int node=s.top();
inst[node]=0;
scc[node]=scccnt;
s.pop();
siz[scccnt]++;
}
s.pop();
scc[u]=scccnt;
inst[u]=0;
siz[scccnt]++;
}
}
bool flg=1;
void build()
{
for (int u=1;u<=n;u++)
{
for (edge e:G1[u])
{
int v=e.v,w=e.w;
if (scc[u]==scc[v]&&w==1)
{
flg=0;
return ;
}
if (scc[u]!=scc[v])
{
G2[scc[u]].push_back({scc[v],w});
in[scc[v]]++;
}
}
}
}
queue<int> q;
int dp[N];
void Topo()
{
memset(dp,0,sizeof(dp));
for (int i=1;i<=scccnt;i++)
{
if (in[i]==0)
{
dp[i]=1;
q.push(i);
}
}
while (!q.empty())
{
int u=q.front();
q.pop();
for (edge e:G2[u])
{
int v=e.v,w=e.w;
in[v]--;
dp[v]=max(dp[v],dp[u]+w);
if (!in[v]) q.push(v);
}
}
}
int main()
{
scanf("%d%d",&n,&k);
int u,v,w;
for (int i=1;i<=k;i++)
{
scanf("%d%d%d",&w,&u,&v);
if (w==1)
{
G1[u].push_back({v,0});
G1[v].push_back({u,0});
}
if (w==2) G1[u].push_back({v,1});
if (w==3) G1[v].push_back({u,0});
if (w==4) G1[v].push_back({u,1});
if (w==5) G1[u].push_back({v,0});
}
for (int i=1;i<=n;i++)
{
if (!dfn[i]) Tarjan(i);
}
build();
if (!flg)
{
printf("-1\n");
return 0;
}
Topo();
long long ans=0;
for (int i=1;i<=scccnt;i++) ans+=((long long)dp[i]*siz[i]);
printf("%lld\n",ans);
return 0;
}
感觉本质上是一样的,但为什么第一份代码判-1挂了。
拜谢。