https://www.luogu.com.cn/training/116#problems
思路:裸的bfs和dfs, 就是需要排个序。
#include
#include
#include
#include
#include
#include
using namespace std;
const int maxn = 1e5 + 10;
int n, m;
bool st[maxn];
vector<int>h[maxn];
void dfs(int u)
{
printf("%d ", u);
st[u] = true;
for(int i = 0;i < h[u].size(); i++)
{
int j = h[u][i];
if(!st[j]) dfs(j);
}
}
void bfs()
{
memset(st, false, sizeof(st));
queue<int>q;
q.push(1);
printf("1 ");
st[1] = true;
while(q.size())
{
int t = q.front();
q.pop();
for(int i = 0;i < h[t].size(); i++)
{
int j = h[t][i];
if(!st[j])
{
st[j] = true;
printf("%d ", j);
q.push(j);
}
}
}
}
int main()
{
scanf("%d%d", &n, &m);
while(m--)
{
int a, b;
scanf("%d%d", &a, &b);
h[a].push_back(b);
}
for(int i = 1;i <= n; i++) sort(h[i].begin(), h[i].end());
dfs(1);
printf("\n");
bfs();
return 0;
}
思路:反向建边,bfs搜一下即可。
#include
#include
#include
#include
#include
using namespace std;
const int maxn = 1e5 + 10;
int n, m;
int h[maxn], e[maxn], ne[maxn], idx;
int ans[maxn];
bool st[maxn];
void add(int x, int y)
{
e[idx] = y;
ne[idx] = h[x];
h[x] = idx++;
}
void bfs(int u)
{
queue<int>q;
q.push(u);
st[u] = true;
while(q.size())
{
int t = q.front();
q.pop();
for(int i = h[t];i != -1;i = ne[i])
{
int j = e[i];
if(!st[j])
{
ans[j] = max(ans[j], u);
q.push(j);
st[j] = true;
}
}
}
}
int main()
{
scanf("%d%d", &n, &m);
memset(h, -1,sizeof(h));
while(m--)
{
int a, b;
scanf("%d%d", &a, &b);
add(b, a);
}
for(int i = n;i >= 1; i--)
{
if(!st[i])
{
bfs(i);
ans[i] = max(ans[i], i);
}
}
for(int i = 1;i <= n; i++) printf("%d ", ans[i]);
return 0;
}
思路:反向建边,拓扑排序。
#include
#include
#include
#include
#include
using namespace std;
const int N = 1e4 + 10, M = 1e6 + 10;
int n, m, ans;
int h[N], e[M], ne[M], idx, w[N], d[N], t[N];
void add(int x, int y)
{
e[idx] = y;
ne[idx] = h[x];
h[x] = idx++;
}
void topsort()
{
queue<int>q;
for(int i = 1;i <= n; i++)
{
if(d[i] == 0)
{
q.push(i);
t[i] += w[i];
ans = max(ans, t[i]);
}
}
while(q.size())
{
int u = q.front();
q.pop();
for(int i = h[u];i != -1; i = ne[i])
{
int j = e[i];
t[j] = max(t[j], t[u]);
d[j]--;
if(d[j] == 0)
{
q.push(j);
t[j] += w[j];
ans = max(ans, t[j]);
}
}
}
}
int main()
{
scanf("%d", &n);
memset(h, -1, sizeof(h));
for(int i = 1;i <= n; i++)
{
int a, b, t;
scanf("%d%d", &a, &t);
w[a] = t;
while(~scanf("%d", &b))
{
if(b == 0) break;
add(b, a);
d[a]++;
}
}
topsort();
printf("%d\n", ans);
return 0;
}
思路:拓扑排序或者dfs + 记忆化搜索都可以, 因为dfs用的不是很熟练这里用dfs + 记忆化搜索写了。数据很大,需要每次都mod。
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int N = 5050, M = 5e5 + 10;
const int mod = 80112002;
int h[N], e[M], ne[M], d[N], idx, ans, n, m;
int res[N];
void add(int x, int y)
{
e[idx] = y;
ne[idx] = h[x];
h[x] = idx++;
}
int dfs(int u)
{
if(h[u] == -1) return 1;
if(res[u]) return res[u];
int sum = 0;
for(int i = h[u];i != -1; i = ne[i])
{
int j = e[i];
sum = (sum + dfs(j)) % mod;
}
res[u] = sum;
return res[u];
}
int main()
{
scanf("%d%d", &n, &m);
memset(h, -1, sizeof(h));
while(m--)
{
int a, b;
scanf("%d%d", &a, &b);
add(a, b);
d[b]++;
}
for(int i = 1;i <= n; i++)
{
if(!d[i])
{
ans = (ans + dfs(i)) % mod;
}
}
printf("%d\n", ans);
}
思路:谜底就在谜面上,跑一遍最长路就行。
#include
#include
#include
#include
#include
using namespace std;
const int N = 2020, M = 5e4 + 10;
int n, m;
int h[N], e[M], ne[M], w[M], idx;
int ans[N];
bool st[N];
void add(int x, int y, int z)
{
w[idx] = z;
e[idx] = y;
ne[idx] = h[x];
h[x] = idx++;
}
void bfs()
{
queue<int>q;
q.push(1);
ans[1] = 0;
st[1] = true;
while(q.size())
{
int t = q.front();
q.pop();
st[t] = false;
for(int i = h[t];i != -1;i = ne[i])
{
int j = e[i];
if(ans[j] < ans[t] + w[i])
{
ans[j] = ans[t] + w[i];
if(!st[j])
{
st[j] = true;
q.push(j);
}
}
}
}
}
int main()
{
scanf("%d%d", &n, &m);
memset(h, -1, sizeof(h));
while(m--)
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
add(a, b, c);
}
for(int i = 1;i <= n; i++)
{
ans[i] = -(int)1e8;
}
bfs();
if(ans[n] == -(int)1e8) printf("-1");
else printf("%d", ans[n]);
}