蒟蒻太难了,34567 TLE
查看原帖
蒟蒻太难了,34567 TLE
75175
huanghaiyang楼主2020/10/8 16:14

蒟蒻第一次写码量这么大的题,但是,,,,,,

是的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; 
} 
2020/10/8 16:14
加载中...