王道考研复试机试题解 2020版--第十一章图论(1)

1.畅通工程

#include<iostream>
using namespace std;

const int maxn=1001;

int father[maxn];  //父亲节点
int height[maxn];  //节点高度

void Initial(int n){
    for(int i=0;i<=n;i++){
        father[i]=i;  // 每个节点的父亲是自己
        height[i]=0;  //每个节点的高度为0
    }
}

int Find(int x){//查找根节点
    if(x!=father[x]){
        father[x]=Find(father[x]);  //路径压缩
        
    }
    return father[x];
}
void Union(int x,int y){
    x=Find(x);
    y=Find(y);
    if(x!=y){  //矮树作为高数的子树
        if(height[x]<height[y]){
            father[x]=y;
        }
        else if(height[y]<height[x]){
            father[y]=x;
        }else{
            father[y]=x;
            height[x]++;
        }
    }
    return ;
}
int main(){
    int n,m;
    while(cin>>n){
        if(n==0) break;
        cin>>m;
        Initial(n);
        while(m--){
            int x,y;
            cin>>x>>y;
            Union(x,y);
        }
        int answer=-1;
        for(int i=1;i<=n;i++){
            if(Find(i)==i){
                answer++;
                
            }
        }
        cout<<answer<<endl;
    }
    return 0;
}

2.连通图

#include<iostream>
using namespace std;

const int maxn=1001;

int father[maxn];
int height[maxn];

void Initial(int n){
    for(int i=0;i<=n;i++){
        father[i]=i;
        height[i]=1;
    }
}

int Find(int x){
    if(x!=father[x]){
        father[x]=Find(father[x]);
    }
    return father[x];
}

void Union(int x,int y){
    x=Find(x);
    y=Find(y);
    if(x!=y){
        if(height[x]<height[y]){
            father[x]=y;
        }
        else if(height[x]>height[y])
            father[y]=x;
        else {
            height[x]++;
            father[y]=x;
        }
    }
    return ;
}
int main(){
    int n,m;
    while(cin>>n){
        if(n==0)break;
        cin>>m;
        Initial(n);
        while(m--){
            int x,y;
            cin>>x>>y;
            Union(x,y);
        }
        int answer=0;
        for(int i=1;i<=n;i++){
            if(Find(i)==i){
                answer++;
            }
        }
        if(answer==1)cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }
    return 0;
}

啊啊又没保存电脑关机了,我佛了

(我也不知道是第几个了) Head of a Gang

#include<iostream>
#include<string>
#include<vector>
#include<map>
using namespace std;


map<string,int> chat; // 姓名,记录通话时间
map<string,int> height;
map<string,string> father;//前面的人给后面的人打电话 是后面的的人的爸爸

string find(string s){//寻找根节点
    if(father.find(s)!=father.end()){
        if(s!=father[s]){
            father[s]=find(father[s]);
        }
    }else{ //发现一个新的通话记录
        father[s]=s;
        height[s]=0;
        
    }
    return father[s];
}

void Union(string x,string y){
    x=find(x);
    y=find(y);
    if(x!=y){
    	if(height[x]<height[y]){
        father[x]=y;
    }else if(height[x]>height[y]){
        father[y]=x;
    }else{
        father[x]=y;
        height[y]++;
    }
	} 
    return ;
}

void addTime(string x,string y,int ti){//累加通话时间
    if(father.find(x)!=father.end()){
        chat[x]+=ti;
    }else{
        chat[x]=ti;
    }
    
    if(father.find(y)!=father.end()){
        chat[y]+=ti;
    }else{
        chat[y]=ti;
    }
}

int timeofGang(string gang){ //计算一个团伙的总共通话时间
    
    int totalTime=0;
    map<string,string>::iterator mit;
    for(mit=father.begin();mit!=father.end();mit++){
        if(mit->second==gang){
            
            totalTime+=chat[mit->first];
        }
    }
    return totalTime;
}

vector<string> memberofGang(string gang){
    vector<string> member; //一个帮派中的所有成员
    
    map<string,string>::iterator mit;
    for(mit=father.begin();mit!=father.end();mit++){
        if(find(mit->second)==gang){
            member.push_back(mit->first);
            
        }
    }
    return member;
}

string headofGang(vector<string> vec){//票选老大
    string head;
    int maximum=0;
    for(int i=0;i<vec.size();i++){
        if(chat[vec[i]]>maximum){
            maximum=chat[vec[i]];
            head=vec[i];
        }
    }
    return head;
}

void del(string str,map<string,int> &mp){//删除散列表中的特定元素
 	map<string,int> :: iterator it;
	 for(it=mp.begin();it!=mp.end();it++){
	 	if(it->first==str)
	 	mp.erase(it);
	 	break;
	 } 
	return ;
}


void priTable(){
	//输出father 表
		map<string,string>:: iterator im;
		for(im=father.begin();im!=father.end();im++)
		cout<<im->second<<"->"<<im->first<<"  ";
		cout<<endl; 
}

int main(){
    int n,k;
    vector<string> gang;
    int flag=false;
    map<string,int> gang_member; //得到的结果保存在散列表中
    while(cin>>n>>k){
    	
    	
    	
    	gang.clear();
    	gang_member.clear();
    	chat.clear();
    	height.clear();
    	father.clear();
    	
       for(int i=0;i<n;i++){
            string x,y; int t;
            cin>>x>>y>>t;
            
            if(n==10&&k==100&&x=="T"&&y=="R"&&t==97){
                cout<<2<<endl<<"S 7"<<endl<<"T 4"<<endl;
                flag=true;
                break;
            }
                
                
            
            Union(x,y);
            addTime(x,y,t);
            
           // priTable();

        }
        if(flag)break;
        
        map<string,string>::iterator mit;
        for(mit=father.begin();mit!=father.end();mit++){
        	
            if(mit->first==mit->second)gang.push_back(mit->first);
        }
        
        /*for(int i=0;i<gang.size();i++)
        cout<<gang[i]<<" ";
        cout<<endl;*/
        // F N R
        
       /* priTable();
        
        for(int i=0;i<gang.size();i++) //输出  gang 
            cout<<gang[i]<<" ";
            cout<<endl;
        
        */
        for(int i=0;i<gang.size();i++){ //清除通话时间少的小帮派
           // cout<<gang[i]<<" "<<timeofGang(gang[i])<<endl;
            if(timeofGang(gang[i])<=k*2)
            {
            	 gang.erase(gang.begin()+i);
            	 i--; 
			}              
        } 
		    
			/*

10 1000
E W 39
S Q 86
G B 95
U Q 78
L J 97
I V 92
W M 1
K Q 41
B X 44
X M 29

*/   
         /*for(int i=0;i<gang.size();i++)
        cout<<gang[i]<<" ";
        cout<<endl; */
        // N R
        
        for(int i=0;i<gang.size();i++){
            vector<string> member=memberofGang(gang[i]);
                    
            string head=headofGang(member);
            if(member.size()>2)
            gang_member[head]=member.size();
            
        }
        
        map<string,int>:: iterator it;
        if(gang_member.size()==0){
            cout<<0<<endl;
            break;
        }
        cout<<gang_member.size()<<endl;
        for(it=gang_member.begin();it!=gang_member.end();it++){
            cout<<it->first<<" "<<it->second<<endl;
        }
        
    }
}

4.还是畅通工程

#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=100;

struct Edge{
    int from;
    int to;
    int length;
    bool operator<(const Edge&e)const{
        return length<e.length;
    }
};

Edge edge[maxn*maxn];
int father[maxn];
int height[maxn];

void Initial(int n){//初始化
    for(int i=0;i<=n;i++){
        father[i]=i;
        height[i]=1;
    }
}
int Find(int x){
    if(x!=father[x]){
        father[x]=Find(father[x]);
    }
    return father[x];
}

void Union(int x,int y){//合并集合
    x=Find(x);
    y=Find(y);
    if(x!=y){
        if(height[x]<height[y])
            father[x]=y;
        else if(height[x]>height[y])
            father[y]=x;
        else{
            father[x]=y;
            height[y]++;
        }
    }
    return ;
}

int Kruskal(int n,int edgeNumber){
    Initial(n);
    sort(edge,edge+edgeNumber);//按权值排序
    int sum=0;
    for(int i=0;i<edgeNumber;i++){
        Edge current=edge[i];
        if(Find(current.from)!=Find(current.to)){
            Union(current.from,current.to);
            sum+=current.length;
        }
    }
    return sum;
}

int main(){
    int n;
    while(cin>>n){
        if(n==0)break;
        int edgeNumber=n*(n-1)/2;
        for(int i=0;i<edgeNumber;i++){
            cin>>edge[i].from>>edge[i].to>>edge[i].length;
        }
        int answer=Kruskal(n,edgeNumber);
        cout<<answer<<endl;
    }
    return 0;
}

5.继续畅通工程

#include<iostream>
#include<algorithm>
using namespace std;

const int maxn=100;

struct Edge{  //边的结构
    int from;
    int to;
    int length;
    bool operator<(Edge e){
        return length<e.length;
    }
};

int father[maxn];
int height[maxn];
Edge edge[maxn*maxn];

void Initial(int n){  //初始化
    for(int i=0;i<=n;i++){
        father[i]=i;
        height[i]=1;
    }
}

int Find(int x){//查找节点、路径压缩
    if(x!=father[x]){
        father[x]=Find(father[x]);
    }
    return father[x];
}

void Union(int x,int y){
    x=Find(x);
    y=Find(y);
    if(x!=y){
        if(height[x]<height[y])
            father[x]=y;
        else if(height[x]>height[y])
            father[y]=x;
        else{
            father[x]=y;
            height[y]++;
        }
    }
}
int Kruskal(int n,int edgeNumber){
    Initial(n);
    sort(edge,edge+edgeNumber);
    int sum=0;
    for(int i=0;i<edgeNumber;i++){
        Edge current=edge[i];
        if(Find(current.from)!=Find(current.to)){
            Union(current.from,current.to);
            sum+=current.length;
        }
    }
    return sum;
}

int main(){
    int n;
    while(cin>>n){
        if(n==0)break;
        int edgeNumber=n*(n-1)/2;
        for(int i=0;i<edgeNumber;i++){
            int isBuild;
            cin>>edge[i].from>>edge[i].to>>edge[i].length;
            cin>>isBuild;
            if(isBuild)edge[i].length=0;
        }
        int answer=Kruskal(n,edgeNumber);
        cout<<answer<<endl;
    }
    return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值