警示后人
查看原帖
警示后人
734703
naroto2022楼主2025/1/6 22:48

这题重边是要计算的,所以,如果你是判点和点之间知否经过的话可能只会有 9191 分,像如下代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define ll long long
using namespace std;
const int MN=1e4+5;
ll n,m,tot,head[MN],low[MN],num[MN],dfn,u[MN],v[MN],c[MN],sta[MN],top,cnt,du[MN],ans;
bool mp[5005][5005];
struct edge{ll to,nxt;}e[MN<<1];
void write(ll n){if(n<0){putchar('-');write(-n);return;}if(n>9)write(n/10);putchar(n%10+'0');}
ll read(){ll x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;}
void add(ll u, ll v){e[++tot].nxt=head[u];head[u]=tot;e[tot].to=v;}
void tarjan(ll u){
    sta[++top]=u;low[u]=num[u]=++dfn;
    for(int i=head[u]; i; i=e[i].nxt){
        ll v=e[i].to;
        if(!mp[u][v]&&!mp[v][u]) mp[u][v]=mp[v][u]=true;
        else continue;
        if(!num[v]){tarjan(v);low[u]=min(low[u],low[v]);}
        else if(!c[v]) low[u]=min(low[u],num[v]);
    }
    if(low[u]==num[u]){
        cnt++;
        while(1){
            ll v=sta[top--];
            c[v]=cnt;
            if(u==v) break;
        }
    }
}
int main(){
    n=read();m=read();
    for(int i=1; i<=m; i++){
        u[i]=read();v[i]=read();
        add(u[i],v[i]);add(v[i],u[i]);
    }
    for(int i=1; i<=n; i++) if(!num[i]) tarjan(i);
    for(int i=1; i<=m; i++) if(c[u[i]]!=c[v[i]]) du[c[u[i]]]++,du[c[v[i]]]++;
    for(int i=1; i<=cnt; i++) if(du[i]==1) ans++;
    write((ans+1)>>1);putchar('\n');
    return 0;
}

正确的应该是用链式前向星来判断是否经过这个边,具体见第一篇题解。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define ll long long
using namespace std;
const int MN=1e4+5;
ll n,m,tot=1,head[MN],low[MN],num[MN],dfn,u[MN],v[MN],c[MN],sta[MN],top,cnt,du[MN],ans;
bool vis[MN];
struct edge{ll to,nxt;}e[MN<<1];
void write(ll n){if(n<0){putchar('-');write(-n);return;}if(n>9)write(n/10);putchar(n%10+'0');}
ll read(){ll x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;}
void add(ll u, ll v){e[++tot].nxt=head[u];head[u]=tot;e[tot].to=v;}
void tarjan(ll u){
    sta[++top]=u;low[u]=num[u]=++dfn;
    for(int i=head[u]; i; i=e[i].nxt) if(!vis[i]){
        ll v=e[i].to;vis[i]=vis[i^1]=true;
        if(!num[v]){tarjan(v);low[u]=min(low[u],low[v]);}
        else if(!c[v]) low[u]=min(low[u],num[v]);
    }
    if(low[u]==num[u]){
        cnt++;
        while(1){
            ll v=sta[top--];
            c[v]=cnt;
            if(u==v) break;
        }
    }
}
int main(){
    n=read();m=read();
    for(int i=1; i<=m; i++){
        u[i]=read();v[i]=read();
        add(u[i],v[i]);add(v[i],u[i]);
    }
    for(int i=1; i<=n; i++) if(!num[i]) tarjan(i);
    for(int i=1; i<=m; i++) if(c[u[i]]!=c[v[i]]) du[c[u[i]]]++,du[c[v[i]]]++;
    for(int i=1; i<=cnt; i++) if(du[i]==1) ans++;
    write((ans+1)>>1);putchar('\n');
    return 0;
}
2025/1/6 22:48
加载中...