HDU-5695-Gym Class
tle选手的成长之路…(果然又tle了)
这道题是16年的百度之星的题目啦~
还是比较简单的~
拓扑排序模板题+贪心
不过我喜欢给函数名字取bfs或者dfs啊。。topsort()这样的函数名我倒是没取过(看个人喜好把~)
中文题面不解释啦~
思路就是拓扑排序emmm.简单的bfs。
就是里面需要贪心一下
贪心策略:在满足约束的情况下尽可能地把ID大的放在前面
所以bfs部分的初始插入队列的时候是从n开始的。这个贪心策略无比明显。就不多说啦~
最后维护一下最小值和累加一下答案就行啦~
维护最小值的地方其实和上次蓝桥模拟赛的一道题很像。
(维护前面出现的最小值)
比较容易啦~
提醒一下:数据有点大。用cin会tle.老实用scanf把。然后记得是ll类型。避免wa.(我注意到了可能会越界。没注意到cin。哭: )。多多丰富经验把~)
代码部分:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
vector<int> v[N];
int in[N];
int n, m;
ll ans[N];
int cnt;
void init()
{
for (int i = 1; i <= n; i++)
{
ans[i] = 0;
v[i].clear();
in[i] = 0;
}
cnt = 0;
}
void bfs()
{
priority_queue<int> q;
for (int i = n; i >= 1; i--)
{
if (!in[i])
{
q.push(i);
}
}
while (!q.empty())
{
int now = q.top();
q.pop();
ans[cnt++] = 1ll * now;
int t = v[now].size();
for (int i = 0; i < t; i++)
{
if (--in[v[now][i]] == 0)
{
q.push(v[now][i]);
}
}
}
}
int main()
{
int t;
scanf ("%d", &t);
while (t--)
{
scanf ("%d%d", &n, &m);
init();
while (m--)
{
int l, r;
scanf ("%d%d", &l, &r);
in[r]++;
v[l].push_back(r);
}
bfs();
ll res = 0;
ll minn = 1e9 + 10;
for (int i = 0; i < cnt; i++)
{
minn = min(minn, ans[i]);
res += minn;
}
cout << res << endl;
}
return 0;
}