传送门:点击打开链接
题意:告诉你n个点,和m条关系,每个关系有u和v,要求u能通过有向边到达v,问要完成这个有向图至少需要多少条边。
思路:就是个xjb的贪心....首先,我们把边按无向图处理,把图分成很多个分块。
对于每个分块,如果这个分块里存在环,那么说明边数>=节点数
对于一个分块,假如我把这些点首尾相连,此时是完美的!因为现在我用了最少的边数,使得可以从一个点到任意一个点,那么无论你给的关系有多么复杂,只要是一个连通图里面的,都是可以做到的。
所以我们就能找出xjb贪心了:
对于一个连通块,如果里面有有向环,那么答案等于点数
如果不存在有向环,答案等于点数-1
然后再xjb搞就行了
#include<map>
#include<set>
#include<cmath>
#include<ctime>
#include<stack>
#include<queue>
#include<cstdio>
#include<cctype>
#include<string>
#include<vector>
#include<cstring>
#include<iomanip>
#include<iostream>
#include<algorithm>
#include<functional>
#define fuck(x) cout<<"["<<x<<"]"
#define FIN freopen("input.txt","r",stdin)
#define FOUT freopen("output.txt","w+",stdout)
using namespace std;
typedef long long LL;
typedef pair<int, int>PII;
const int MX = 2e5 + 5;
const int INF = 0x3f3f3f3f;
struct Edge {
int v, nxt, sign;
} E[MX];
int Head[MX], rear;
void edge_init() {
rear = 0;
memset(Head, -1, sizeof(Head));
}
void edge_add(int u, int v, int s) {
E[rear].v = v;
E[rear].nxt = Head[u];
E[rear].sign = s;
Head[u] = rear++;
}
int n, m;
int A[MX], cnt[MX], cir[MX], vis[MX], siz;
int DFS1(int u, int id) {
A[u] = -1;
int ret = 1;
for(int i = Head[u]; ~i; i = E[i].nxt) {
int v = E[i].v;
if(!A[v]) ret += DFS1(v, id);
}
A[u] = id;
return ret;
}
bool DFS2(int u) {
vis[u] = -1;
bool ret = false;
for(int i = Head[u]; ~i; i = E[i].nxt) {
int v = E[i].v;
if(E[i].sign) {
if(vis[v] == -1) {
ret = true; break;
}
if(!vis[v] && DFS2(v)) {
ret = true; break;
}
}
}
vis[u] = 1;
return ret;
}
int solve() {
siz = 0;
memset(A, 0, sizeof(A));
memset(cir, 0, sizeof(cir));
memset(cnt, 0, sizeof(cnt));
memset(vis, 0, sizeof(vis));
for(int i = 1; i <= n; i++) {
if(!A[i]) siz++, cnt[siz] = DFS1(i, siz);
if(!vis[i] && DFS2(i)) cir[A[i]] = 1;
}
int ans = 0;
for(int i = 1; i <= siz; i++) {
if(cir[i]) ans += cnt[i];
else ans += cnt[i] - 1;
}
return ans;
}
int main() {
edge_init(); //FIN;
scanf("%d%d", &n, &m);
for(int i = 1; i <= m; i++) {
int u, v;
scanf("%d%d", &u, &v);
edge_add(u, v, 1);
edge_add(v, u, 0);
}
printf("%d\n", solve());
return 0;
}
1837

被折叠的 条评论
为什么被折叠?



