T103481 【模板】割边 洛谷

原题链接​|​​​​​T103481 【模板】割边 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

主要是分享一个数据生成器(生成输入数据,再拿我下面的ac代码跑出输出结果就行,自己debug去,乐):

#include <iostream>
#include <vector>
#include <random>

using namespace std;

int main() {
    // 随机数生成器
    random_device rd;
    mt19937 gen(rd());

    int n = 10;  // 节点数量
    int m = 13; // 边数量

    cout << n << " " << m << endl;

    // 生成图的边
    vector<pair<int, int>> edges;
    for (int i = 1; i <= m; i++) {
        int u = uniform_int_distribution<int>(1, n)(gen);
        int v = uniform_int_distribution<int>(1, n)(gen);

        cout << u << " " << v << endl;
    }

    return 0;
}

ac代码:(因为原题不能下载数据,所以跑过来发一篇博客)

代码直接拿自己的ac代码过来贴的,有几个板子,因为懒得改了,就这么发了。

# include  <bits/stdc++.h>
using  namespace  std ;

namespace predefine {
const long long inf = 0x3f3f3f3f3f3f3f3f ;
using ll = long long ;
using Int = __int128 ;
using pll = pair < ll , ll > ;
# define  IOS  iostream::sync_with_stdio ( 0 ) ; cin.tie ( 0 ) ;

# define af( i , a , b ) for ( ll i = a ; i <= b ; ++ i )
# define df( i , a , b ) for ( ll i = a ; i >= b ; -- i )

# define Dg( x ) cout << " ------- " <<  x << " ------- " << '\n'
# define Dged Dg ( "Debug ed" )
# define Dgop Dg ( "Debug op" )
# define pr( x ) cout << #x << " = " << x << '\n'
# define pn putchar ('\n') 
# define ps cout << "yes" 
# define __fin( a ) freeopen ( a , "r" , stdin ) 
# define __fout( a ) freeopen ( a , "+w" , stdout ) 

# define lowbit( x ) ( x & ( - x ) ) 

// # define endl '\n'
}
using namespace predefine ;

const ll maxn = 2e5 + 10 ;

const ll mod = 1e9 + 7 ;
//-----  板子  ---------------------------------------------------------------------------------------------------------
struct SCC {
	using i64 = long long ;
	i64 n , cnt = 0 , tot = -1 ;
	vector < vector < i64 > > mp ;
	vector < i64 > d , id , stack , tag , size , val ;
	vector < bool > instack ;
	
	explicit SCC ( ll n , vector < vector < i64 > >& mp , vector < ll > &val ) : 
		n ( n ) , mp ( mp ) , val ( val ) , d ( vector < i64 > ( n , -1 ) ) , id ( vector < i64 > ( n ) ) ,
			tag ( vector < i64 > ( n , -1 ) ) , instack ( vector < bool > ( n , 0 ) ) {}
private:
	void __scc ( ll now ) {
//		ps ;
		d [ now ] = id [ now ] = ++ tot ;
		stack.push_back ( now ) ; instack [ now ] = 1 ;
		for ( auto u : mp [ now ] ) {
			if ( !~d [ u ] ) {
				__scc ( u ) ;
				id [ now ] = min ( id [ now ] , id [ u ] ) ;
			}
			else if ( instack [ u ] ) {
				id [ now ] = min ( id [ now ] , id [ u ] ) ;
			}
		}
		if ( d [ now ] == id [ now ] ) {
			++ cnt ;
			size.push_back ( 0 ) ;
			do {
				size.back () += val [ stack.back () ] ;
				instack [ stack.back () ] = 0 ;
				tag [ stack.back () ] = cnt ;
				stack.pop_back () ;
			} while ( instack [ now ] ) ;
		}
	}
public:
	void scc ( ll now ) {
		-- cnt ;
		__scc ( now ) ;
		++ cnt ;
	}
};
struct CPT {

	ll n , tot = -1 , root = -1 ;
	vector < vector < ll > > mp ;
	vector < ll > d , id ;
	vector < bool > iscp ;

	explicit CPT ( ll n , vector < vector < ll > >& mp ) :
		 n ( n ) , mp ( mp ) , d ( vector < ll > ( n , -1 ) ) ,
		  id ( vector < ll > ( n , -1 ) ) , iscp ( vector < bool > ( n , 0 ) ) {} ;
	
private:
	void __cutpoint ( ll now ) {
		d [ now ] = id [ now ] = ++ tot ;
		ll child = 0 ;
		for ( auto u : mp [ now ] ) {
			if ( !~d [ u ] ) {
				__cutpoint ( u ) ;
				id [ now ] = min ( id [ now ] , id [ u ] ) ;
				if ( id [ u ] >= d [ now ] ) {
					++ child ;
					if ( now != root || child >= 2 ) {
						iscp [ now ] = 1 ;
					}
				}
			}
			else id [ now ] = min ( d [ u ] , id [ now ] ) ;
		}
	}

public:
	void cutpoint ( ll now , ll root ) {
		this ->root = root ;
		__cutpoint ( now ) ;
		this ->root = -1 ;
	}

};

struct CEG {

	ll n , tot = -1 ; 
	vector < pll > edge ;
	vector < vector < ll > > mp ;
	vector < ll > d , id ;
	vector < ll > ans ;

	explicit CEG ( ll n ) : 
		 n ( n ) , d ( vector < ll > ( n , -1 ) ) , id ( vector < ll > ( n , - 1 ) ) ,
		 	mp ( vector < vector < ll > > ( n ) ) {} ;

private :
	void __cutedge ( ll now , ll __edge ) {
		d [ now ] = id [ now ] = ++ tot ;
		for ( auto tag : mp [ now ] ) {
			auto& here = edge [ tag ].second ;
			if ( !~d [ here ] ) {
				__cutedge ( here , tag ) ;
				id [ now ] = min ( id [ now ] , id [ here ] ) ;
				if ( id [ here ] > d [ now ] ) {
					ans.push_back ( tag ) ;
				}
			}
			else if ( tag != ( __edge ^ 1 ) ) {
				id [ now ] = min ( id [ here ] , id [ now ] ) ;
			}
		}
	}
 
public:
	void add ( ll u , ll v ) {
		edge.emplace_back ( u , v ) ;
		mp [ u ].push_back ( (ll)edge.size () - 1 ) ;
	}
	void cutedge ( ll u , ll __edge ) {
		__cutedge ( u , __edge ) ;
	}
};
//-----  板子  ---------------------------------------------------------------------------------------------------------

Int Pow ( Int a , Int b ) { 
	a = a ; Int ans = 1 ; 
	for ( ; b ; b >>= 1 ) { if ( b & 1 ) ans = ( a * ans ) ; a = ( a * a ) ; } 
	return ans ; }

ll Pow ( ll a , ll b , ll mod ) { 
	a = a % mod ; ll ans = 1 ; 
	for ( ; b ; b >>= 1 ) { if ( b & 1 ) ans = ( a * ans ) % mod ; a = ( a * a ) % mod ; } 
	return ans ; }

inline ll sum1 ( ll _a ) { return ( _a * ( _a + 1 ) ) >> 1 ; }
inline ll sum2 ( ll _b ) { return _b * ( _b + 1 ) * ( 2 * _b + 1 ) / 6  ; }

ll dx [ 4 ] = { -1 , 0 , 1 , 0 } ;
ll dy [ 4 ] = { 0 , 1 , 0 , -1 } ;

void solve ()
{
	ll n , m ; 
	cin >> n >> m ;

	CEG g ( n ) ;
	auto add = [ & ] ( ll& u , ll& v ) {
		g.add ( u , v ) ;
	};
	
	// map < ll , pll > mp ;

	af ( i , 0 , m - 1 ) {
		ll u , v ; cin >> u >> v ;
		-- u , -- v ;
		// mp [ i ] = { u , v } ;
		add ( u , v ) ; add ( v , u ) ;
//		ps ;
	}
	
	af ( i , 0 , n - 1 ) {
		if ( !~g.d [ i ] ) {
			g.cutedge ( i , inf ) ;
		}
	}
	cout << g.ans.size () << endl ;
	
	// map < pll , ll > mp1 ;
	 
	// for ( auto u : g.ans ) {
	// 	auto& [ x , y ] = g.edge [ u ] ;
	// 	++ mp1 [ { x , y } ] ;
	// 	++ mp1 [ { y , x } ] ;
	// }
	
	// for ( auto& [ _ , u ] : mp ) {
	// 	if ( mp1 [ u ] ) {
	// 		auto& [ x , y ] = u ;
	// 		cout << x + 1 << ' ' << y + 1  << endl ;
	// 	}
	// }
}	

int  main () {
//	IOS
	// init () ;
	ll _ = 1 ;
	// cin >> _ ;
	while ( _ -- ) {
		solve () ;
	} 
	return 0 ;
}

/*
//-----  数据  ---------------------------------------------------------------------------------------------------------
1
3 5
011
1
100
000
3
010
100
2
110
000
3
000
000
3
001
000
1
end of file
----------
*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值