题目链接:
https://www.luogu.org/problem/P3387
一:ac思路
参考博客:
https://www.luogu.org/blog/wyz598085788/solution-p3387
思路:
1:在用tarjan缩点时,用num[cnt]记录每一个强连通分量的值
2:核心思路:虚拟头节点f和虚拟尾节点t
3:就是经过tarjan缩点之后,把每一个强连通分量看作一个节点建图,然后把每一个强连通分量的负值当作该边的权值
4:以f为起点,t为终点跑spfa
5:用虚拟头节点f和每一个节点建一条边,权值为-num[i],每一个节点和虚拟尾节点建一条边,权值为0
int f=0;
int t=cnt+1;
for(int i=1;i<=cnt;i++)
{
mapp[f].push_back(make_pair(i,-num[i]));
mapp[i].push_back(make_pair(t,0));
}
#include
using namespace std;
const int maxn=1e4+1;
vectore[maxn];
setee[maxn];
int dfn[maxn],low[maxn],ins[maxn],color[maxn],timing,cnt,n,m,id[maxn];
int num[maxn],point[maxn];
stacks;
vector >mapp[maxn];
int d[maxn],ing[maxn];
void tarjan(int x)
{
low[x]=dfn[x]=++timing;
s.push(x);
ins[x]=1;
for(int i=0;iq;
q.push(x);
d[x]=0;
ing[x]=1;
while(!q.empty())
{
int now=q.front();
q.pop();
ing[now]=0;
for(int i=0;id[now]+mapp[now][i].second)
{
d[v]=d[now]+mapp[now][i].second;
if(ing[v])
continue;
q.push(v);
ing[v]=1;
}
}
}
return -d[t];
}
int main()
{
ios::sync_with_stdio(0);
cin>>n>>m;
for(int i=1;i<=n;i++)
{
int x;
cin>>x;
point[i]=x;
}
for(int i=1;i<=m;i++)
{
int a,b;
cin>>a>>b;
e[a].push_back(b);
}
for(int i=1;i<=n;i++)
{
if(!dfn[i])
tarjan(i);
}
for(int i=1;i<=n;i++)
{
for(int j=0;j
二:让自己纠结多日的90分,9个测试点ac一个wa的代码
错因:
1:没有正确处理从哪一个节点开始spfa,到哪一个点的最长路径
2:一开始处理为spfa的起点为入度为零的节点,到出度为零的节点,的最长路径,然后从中取最大值
#include
using namespace std;
const int maxn=1e4+1;
vectore[maxn];
setee[maxn];
int dfn[maxn],low[maxn],ins[maxn],color[maxn],timing,cnt,n,m,id[maxn];
int num[maxn],point[maxn];
stacks;
vector >mapp[maxn];
int d[maxn],ing[maxn];
void tarjan(int x)
{
low[x]=dfn[x]=++timing;
s.push(x);
ins[x]=1;
for(int i=0;iq;
q.push(x);
d[x]=0;
ing[x]=1;
while(!q.empty())
{
int now=q.front();
q.pop();
ing[now]=0;
for(int i=0;id[now]+mapp[now][i].second)
{
d[v]=d[now]+mapp[now][i].second;
if(ing[v])
continue;
q.push(v);
ing[v]=1;
}
}
}
int mi=1e9;
for(int i=1;i<=cnt;i++)
{
if(ee[i].size()==0)
{
mi=min(d[i],mi);
}
}
return -mi;
}
int main()
{
ios::sync_with_stdio(0);
cin>>n>>m;
for(int i=1;i<=n;i++)
{
int x;
cin>>x;
point[i]=x;
}
for(int i=1;i<=m;i++)
{
int a,b;
cin>>a>>b;
e[a].push_back(b);
}
for(int i=1;i<=n;i++)
{
if(!dfn[i])
tarjan(i);
}
for(int i=1;i<=n;i++)
{
for(int j=0;j