Note
图的遍历 DFS 注意分辨边权 与点权 !!!本道题就是利用点权。 数组不能只开到1010,会出现段错误… ans记得排序。按字母表顺序可以用:
bool compare ( string a, string b) {
return a + b < b + a;
}
Code
#include <bits/stdc++.h>
using namespace std;
struct node{
int id, weight;
node ( int i, int w) {
id= i;
weight= w;
}
} ;
int n, k, index_= 1 ;
map< string, int > toId;
map< int , string> toName;
vector< int > v[ 2010 ] ;
vector< node> vn, ans;
int weight[ 2010 ] ;
bool visit[ 2010 ] = { false } ;
bool cmp ( node a, node b) {
return a. weight> b. weight;
}
bool cmp_alpha ( node a, node b) {
return toName[ a. id] + toName[ b. id] < toName[ b. id] + toName[ a. id] ;
}
int NameToId ( string s) {
if ( toId[ s] == 0 ) toId[ s] = index_++ ;
return toId[ s] ;
}
void dfs ( int root) {
visit[ root] = true ;
vn. push_back ( node ( root, weight[ root] ) ) ;
for ( int i= 0 ; i< v[ root] . size ( ) ; i++ ) {
if ( visit[ v[ root] [ i] ] == false )
dfs ( v[ root] [ i] ) ;
}
return ;
}
int main ( ) {
#ifndef ONLINE_JUDGE
freopen ( "data.txt" , "r" , stdin ) ;
#endif
memset ( weight, 0 , sizeof ( weight) ) ;
int id1, id2, t;
string s1, s2;
scanf ( "%d %d" , & n, & k) ;
for ( int i= 1 ; i<= n; i++ ) {
cin>> s1>> s2>> t;
id1= NameToId ( s1) ;
id2= NameToId ( s2) ;
toName[ id1] = s1;
toName[ id2] = s2;
v[ id1] . push_back ( id2) ;
v[ id2] . push_back ( id1) ;
weight[ id1] + = t;
weight[ id2] + = t;
}
for ( int i= 1 ; i< index_; i++ ) {
if ( visit[ i] == false ) {
int sum= 0 ;
vn. clear ( ) ;
dfs ( i) ;
sort ( vn. begin ( ) , vn. end ( ) , cmp) ;
for ( int i= 0 ; i< vn. size ( ) ; i++ ) {
sum+ = vn[ i] . weight;
}
if ( vn. size ( ) > 2 && sum> 2 * k) {
ans. push_back ( node ( vn[ 0 ] . id, vn. size ( ) ) ) ;
}
}
}
printf ( "%d\n" , ans. size ( ) ) ;
sort ( ans. begin ( ) , ans. end ( ) , cmp_alpha) ;
for ( int i= 0 ; i< ans. size ( ) ; i++ ) {
printf ( "%s %d\n" , toName[ ans[ i] . id] . c_str ( ) , ans[ i] . weight) ;
}
return 0 ;
}