蒟蒻第一次写码量这么大的题,但是,,,,,,
是的TLE了
不过用的算法和题解都是一样的。。。
测试的时候发现是SPFA里面有问题(或者是新建图的时候有问题), 但是着实不知道怎么改 谢谢大佬们了!
#include <bits/stdc++.h>
#include <queue>
using namespace std;
const int maxn = 500100;
int n, m, s, p, t;//图的信息
int val[maxn], last[maxn], bar[maxn];
struct edge
{
int to;
int next;
}e[maxn], newe[maxn];
int DFN[maxn], Low[maxn], st[maxn];//tarjan
bool vis[maxn];
int num, top;
int belong[maxn], cnt;//缩点
int newlast[maxn], newbar[maxn];//新图信息
long long newval[maxn]; //理论上int存不下
bool newbarcnt[maxn];
int newt, newcnt;
queue <int> q;//SPFA
bool b[maxn];
long long dis[maxn];
int head, tail;
long long ans;
void add_edge(int x, int y)
{
e[last[x]].to = y;
e[last[x]].next = ++ t;
last[x] = t;
}
void add_newedge(int x, int y)
{
newe[newlast[x]].to = y;
newe[newlast[x]].next = ++ newt;
newlast[x] = newt;
}
void tarjan(int i)
{
DFN[i] = Low[i] = ++ num;
st[++ top] = i;
vis[i] = true;
for(int j = i, to ; e[j].to != 0 ; j = e[j].next)
{
to = e[j].to;
if(!DFN[to])
{
tarjan(to);
Low[i] = min(Low[i], Low[to]);
}
else if(vis[to])
Low[i] = min(Low[i], DFN[to]);
}
if(DFN[i] == Low[i])
{
cnt ++;
do//其实可以在这里就建新图
{
belong[st[top]] = cnt;
vis[st[top]] = false;
top --;
}while(st[top + 1] != i);
}
}
void SPFA()
{
//for(int i = 1 ; i <= cnt ; i ++) dis[i] = 0;
s = belong[s];
dis[s] = newval[s];
q.push(s);
b[s] = true;
while(!q.empty())
{
head = q.front();
q.pop();
b[head] = false;
for(int i = head ; newe[i].to != 0 ; i = newe[i].next)
{
tail = newe[i].to;
if(dis[tail] < dis[head] + newval[tail])
{
dis[tail] = dis[head] + newval[tail];
if(!b[tail])
{
b[tail] = true;
q.push(tail);
}
}
}
}
}
inline int read(int &a)
{
a = 0;
char c = getchar();
while(c > '9' || c < '0') c = getchar();
while(c >= '0' && c <= '9')
{
a = a * 10 + c - '0';
c = getchar();
}
}
int main()
{
freopen("in.txt", "r", stdin);
read(n), read(m);
t = n;
for(int i = 1 ; i <= n ; i ++) last[i] = i;
for(int i = 1, a, b ; i <= m ; i ++)
{
read(a), read(b);
add_edge(a, b);
}
for(int i = 1 ; i <= n ; i ++) read(val[i]);
read(s), read(p);
for(int i = 1 ; i <= p ; i ++) read(bar[i]);
for(int i = 1 ; i <= n ; i ++)//将这个图的强连通分量全部缩点了之后就只用求单元最短路径
if(!DFN[i])
tarjan(i);
newt = cnt;
for(int i = 1 ; i <= cnt ; i ++) newlast[i] = i;
for(int i = 1 ; i <= n ; i ++)
{
for(int j = i ; e[j].to != 0 ; j = e[j].next)
if(belong[i] != belong[e[j].to])
add_newedge(belong[i], belong[e[j].to]);//建新图
newval[belong[i]] += val[i];//累计权值
}
for(int i = 1 ; i <= p ; i ++)
{
if(!newbarcnt[belong[bar[i]]])
newbar[++ newcnt] = belong[bar[i]], newbarcnt[belong[bar[i]]] = true;
}
SPFA();
for(int i = 1 ; i <= newcnt ; i ++) ans = max(ans, dis[newbar[i]]);
printf("%lld", ans);
return 0;
}