法1、在拓扑排序里求dist
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int N = 10010 , M = 20010;
int n , m;
int e[M] , ne[M] , h[N] , idx;
int ans[N] , d[N];
int q[N];
void add(int a, int b)
{
e[idx] = b , ne[idx] = h[a] , h[a] = idx++;
}
bool topsort()
{
memset(ans , 0x3f , sizeof ans);
int hh = 0 , tt = -1;
for(int i = 1 ; i <= n ; i++)
if(!d[i])
{
q[++tt] = i;
ans[i] = 100;
}
while(hh <= tt)
{
int t = q[hh++];
for(int i = h[t] ; ~i ; i = ne[i])
{
int j = e[i];
if(--d[j] == 0)
{
q[++tt] = j;
ans[j] = ans[t] + 1;
}
}
}
return tt == n - 1;
}
int main()
{
cin >> n >> m;
memset(h , -1 , sizeof h);
while(m--)
{
int a , b;
scanf("%d%d" , &a , &b);
add(b , a);
d[a]++;//入度加一
}
if(!topsort()) puts("Poor Xed");
else
{
int res = 0;
for(int i = 1 ; i <= n ; i++)
res += ans[i];
cout << res << endl;
}
return 0;
}
求完拓扑排序后,在拓扑序的基础上求最长路
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int N = 10010 , M = 20010;
int n , m;
int e[M] , ne[M] , h[N] , idx;
int dist[N] , d[N];
int q[N];
void add(int a, int b)
{
e[idx] = b , ne[idx] = h[a] , h[a] = idx++;
}
bool topsort()
{
int hh = 0 , tt = -1;
for(int i = 1 ; i <= n ; i++)
if(!d[i])
{
q[++tt] = i;
}
while(hh <= tt)
{
int t = q[hh++];
for(int i = h[t] ; ~i ; i = ne[i])
{
int j = e[i];
if(--d[j] == 0)
q[++tt] = j;
}
}
return tt == n - 1;
}
int main()
{
cin >> n >> m;
memset(h , -1 , sizeof h);
while(m--)
{
int a , b;
scanf("%d%d" , &a , &b);
add(b , a);
d[a]++;//入度加一
}
if(!topsort()) puts("Poor Xed");
else
{
int res = 0;
for(int i = 1 ; i <= n ; i++) dist[i] = 100;
for(int i = 0 ; i < n ; i++)
{
int t = q[i];
for(int k = h[t] ; ~k ; k = ne[k])
{
int j = e[k];
dist[j] = max(dist[j] , dist[t] + 1);
}
}
for(int i = 1 ; i <= n ; i++)
res += dist[i];
cout << res << endl;
}
return 0;
}
法一批注打错字了,入度()
这道题为什么不能直接顺着建边, 求出最长链, 然后减去啊
没明白你什么意思
大概就是不反向建图, 应该得奖学金多的人的dist就少, 求出最大的dist然后把每个人的dist值都用它减, 应该也是对的啊, 拍了半天没找到小数据错误
你试试这个样例输出多少,我不知道我有没有理解你的想法
4 3
1 2
2 3
4 3
应该输出404
懂了! 谢谢dalao, 意思是只固定住了右端点, 不可以按左端点算对吗。 (原谅我语文太差了qaq)
加油hh~
还是不太明白为什么拓扑排序能求最长路
根据拓扑序,当且仅当没有点能更新这个点的时候(没有前驱节点)才用这个点去更新它的后继节点,已经求出dist[u]那么就可以去更新u的后继节点了