daitouzero @ 2023-01-16 16:34:27
就是先拿Tarjon缩点再拓补排序
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<bitset>
#include<vector>
#include<set>
#define X 20005
#define ll long long
#define MOD 998244353
using namespace std;
inline int Max(int a,int b) {return a>b?a:b;}
inline int Min(int a,int b) {return a<b?a:b;}
inline void Swap(int &a,int &b) {a=a^b;b=a^b;a=a^b;}
inline int scan()
{
register int x=0,f=0;
register char c=getchar();
while(c<'0') f|=(c=='-'),c=getchar();
while(c>='0') x=(x<<1)+(x<<3)+(c&15),c=getchar();
return f?-x:x;
}
inline void print(int x,char c)
{
if (x<0) {x=-x;putchar('-');}
if(x/10) print(x/10,0);
putchar(x%10+48);
if (c) putchar(c);
}
int n,m,x;
vector<int>edge[1000005];
set<int>point[1000005];
int size[1000005];
int dfn[1000005],low[1000005],Time;
bool instack[1000005];
int top,stack[1000005];
int color,col[1000005];
void Tarjon(int s)
{
instack[s]=true;
top++;
stack[top]=s;
Time++;
dfn[s]=Time;
low[s]=dfn[s];
for (int i=0,Next;i<edge[s].size();i++)
{
Next=edge[s][i];
if (dfn[Next]==0)
{
Tarjon(Next);
low[s]=Min(low[s],low[Next]);
}
else if (instack[Next]) low[s]=Min(low[s],dfn[Next]);
}
if (dfn[s]==low[s])
{
int pos;
color++;
do
{
pos=stack[top];top--;
instack[pos]=false;
col[pos]=color;
size[color]++;
}while (pos!=s);
}
}
int in[1000005],dist[1000005];
int longlink,waycnt[1000005],longlinkcnt;
int head,tail,dl[1000005];
inline void Topsort()
{
int pos;
set<int>::iterator Next;
while (head<tail)
{
head++;
pos=dl[head];
for (Next=point[pos].begin();Next!=point[pos].end();Next++)
{
if (dist[pos]+size[*Next]>dist[*Next])
{
dist[*Next]=dist[pos]+size[*Next];
waycnt[*Next]=waycnt[pos];
}
else if (dist[pos]+size[*Next]==dist[*Next])
{
waycnt[*Next]+=waycnt[pos];
waycnt[pos]%=x;
}
in[*Next]--;
if (in[*Next]==0) tail++,dl[tail]=*Next;
}
}
}
int main()
{
n=scan();m=scan();x=scan();
for (int i=1,u,v;i<=m;i++)
{
u=scan();v=scan();
edge[u].push_back(v);
}
for (int i=1;i<=n;i++)
if (dfn[i]==0) Tarjon(i);
for (int i=1;i<=n;i++)
for (int e=0,Next;e<edge[i].size();e++)
{
Next=edge[i][e];
if (col[i]!=col[Next])
{
point[col[i]].insert(col[Next]);
in[col[Next]]++;
}
}
//print(color,'\n');
for (int i=1;i<=color;i++)
{
if(in[i]==0) tail++,dl[tail]=i;
waycnt[i]=1;dist[i]=size[i];
}
Topsort();
for (int i=1;i<=n;i++)
{
if (longlink<dist[i])
{
longlink=dist[i];
longlinkcnt=waycnt[i];
}
else if (longlink==dist[i])
longlinkcnt=(longlinkcnt+waycnt[i])%x;
}
print(longlink,'\n');
print(longlinkcnt,'\n');
return 0;
}
by daitouzero @ 2023-01-16 22:31:04
破案了
重边判了but统计入度的时候把重边一起算了
此贴完结