题意:一群人编号1~n,给他们拓扑排序,已知其中的邻接关系,要求得到的拓扑序中,每个元素包括自己以及他前面的编号的最小值最大,求所有人的这个值的和。
思路:把正常拓扑排序的队列换成优先队列即可
//做的时候手滑把用于记录的变量和循环的变量名写重了结果t了一个晚上
//发现用for初始化比用memset初始化速度快,而且更省内存
#include <bits/stdc++.h>
using namespace std;
vector<int> adjl[100010];
long long c,su;
int v,e,s,t,in[100010];int ans[100010],countt;
void top_sort()
{priority_queue<int> q;
for(int i=v;i>=1;i--)
if(in[i]==0)
q.push(i);
while(!q.empty())
{
int vt=q.top();
q.pop();
ans[countt++]=vt;
//c=min((long long)vt,c);
//su+=c<vt?c:c=vt;
for(int i=0;i<adjl[vt].size();i++)
{
in[adjl[vt][i]]--;
if(in[adjl[vt][i]]==0)
{
q.push(adjl[vt][i]);
}
}
}
}
int main()
{
int tt;
scanf("%d",&tt);
while(tt--)
{
scanf("%d%d",&v,&e);
su=0;
/* memset(adjl,0,sizeof(adjl));
memset(in,0,sizeof(in));*/
for(int i=1;i<=v;i++){adjl[i].clear();in[i]=0;}
for(int i=0;i<e;i++)
{
scanf("%d%d",&s,&t);
adjl[s].push_back(t);
in[t]++;
}
countt=0;
top_sort();
c=INFINITY;
for(int i=0;i<countt;i++)
{
//su+=c<ans[i]?c:c=ans[i];
c=c>ans[i]?ans[i]:c;
su+=c;
}
printf("%I64d\n",su);
//for(int i=0;i<vec.size();i++)cout<<vec[i]<<" ";
// cout<<su<<endl;
}
return 0;
}