传送门:https://codeforces.com/contest/107/problem/A
题意:
给n个点(房子)和p条管道(单向边)
每条管道
a
i
,
b
i
,
d
i
a_i,b_i,d_i
ai,bi,di表示水流能通过该管道从
a
i
a_i
ai流向
b
i
b_i
bi,该管道直径为
d
i
d_i
di
- 对每个点,最多有一个出水口和一个进水口
- 在每个有出水口而没有进水口的点安装水箱,也就是水流的起点
- 在每个有进水口而没有出水口的点安装水龙头,也就是水流的终点
求每个水箱输出到水龙头的水流的最大值,也就是求路径上管道的最小直径
思路:
每个点最多只能有一个出水口和一个入水口,所以这个图是由一条条链组成的
遍历所有的点找链的起点,
对于每个起点,dfs搜到链的终点,维护最小的管道直径即可
注意:可能存在既没有入水口,也没有出水口的单点情况,这种情况不用计算入答案。
AC代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e3+10,inf=0x3f3f3f3f;
int n,p,a,b,d,ans=0,dis[maxn][maxn],nxt[maxn];
map<int,int> mp;//记录入度
void dfs(int sta,int now,int mnd) {//起点、当前所在点、当前链最小直径
if(nxt[now]==0) { //没有出水口,到达链的终点
printf("%d %d %d\n",sta,now,mnd);
return ;
}
dfs(sta,nxt[now],min(mnd,dis[now][nxt[now]]));
}
int main() {
cin>>n>>p;
for(int i=0; i<p; i++) {
cin>>a>>b>>d;
nxt[a]=b,mp[b]++,dis[a][b]=d;
}
for(int i=1; i<=n; i++) if(!mp[i] && nxt[i]!=0) ans++;//考虑入度为0,出度不为0
printf("%d\n",ans);
for(int i=1; i<=n; i++) {
if(!mp[i] && nxt[i]!=0) dfs(i,i,inf);
}
}