UVA506相互依赖的关系,以及ID_NAME转换的使用

遇到这种字符串做各种运算的情况,最好的方式就是将其转换为id的形式,每一个整数代表一个顶点。

在转换的时候,name_id可以使用map,id转那么就最好使用数组或者vector,因为容易调试。

 

在图论里面,像这种顶点个数不明以及顶点数很多的情况,需要像这道题这样,使用vector来保存节点和节点之间的关系。

但是需要多次保存相互之间的权值的情况不可以使用这种方式来保存,还是得使用数组来保存。

如果不想使用sstream的,想使用s.find()然后断成字串的时候,只适合于只寻找一次的情况,需要多次寻找还是得使用stream。

下面附上UVAOJ崩了的时候的不知道是否AC了的代码

//这道题我他妈就没有看懂,还是看的汝佳大神的书才把题目给搞懂
//难点在于如何保存安装的顺序
//以及如何保存不知道顶点个数的图?
#include<iostream>
#include<cstdio>
#include<sstream>
#include<cstring>
#include<vector>
#include<string>
#include<map>
using namespace std;

const int maxn = 10000 + 10;
int status[maxn];
int cnt = 0;
vector<string>ID_name;
map<string,int>name_ID;
vector<int>dep[maxn];
vector<int>dep2[maxn];

vector<int>seq;
void print_relation()
{
    for(int i = 0 ; i < ID_name.size();i++)
    {
        cout<<ID_name[i]<<"受.....的支持"<<endl;
        for(int j = 0;j < dep[i].size(); j++)
        {
            cout<<ID_name[dep[i][j]]<<endl;
        }
        cout<<"支持谁"<<endl;
        for(int j_1 = 0;j_1 < dep2[i].size();j_1++)
        {
            cout<<ID_name[dep[i][j_1]]<<endl;
        }
    }
    printf("\n");
}
void install(int id,int flag)
{
    
    for(int i = 0; i < dep[id].size();i++)
    {
        if(!status[dep[id][i]])
        {
            install(dep[id][i],1);//隐式安装
        }
    }
    cout<<"   Installing "<<ID_name[id]<<endl;
    status[id] = flag;
    seq.push_back(id);
}
int ID(string name)
{
    if(!name_ID.count(name))
    {
        name_ID[name] = cnt;
        ID_name.push_back(name);
        cnt++;
        return cnt - 1;
    }
    else
        return name_ID[name];
}
void remove(int id,int flag)
{
    for(int i = 0;i<dep2[id].size();i++)
    {
        if(status[dep2[id][i]])
        {
            if(flag == 2)
            {
                cout<<"   "<<ID_name[id]<<" is still needed."<<endl;
            }
            return ;//不可以删除,因为
        }
    }
    if(status[id] <= flag)
    {    
        status[id] = 0;
        for(int i = 0;i < seq.size();i++)
        {
            if(seq[i] == id)
            {
                seq.erase(seq.begin() + i);
                cout<<"   Removing "<<ID_name[id]<<endl;
                break;
            }
        }
    }
    for(int i_0 = 0;i_0 < dep[id].size();i_0++)
    {
        if(status[dep[id][i_0]] == 1)
            remove(dep[id][i_0],1);
    }
}
void list_all()
{
    for(int i = 0;i < seq.size();i++)
    {
        cout<<"   "<<ID_name[seq[i]]<<endl;
    }
}

int main()
{
#ifdef local
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
#endif
    string line;
    while(getline(cin,line))
    {
        cout<<line<<endl;
        if(line[0] == 'E')
            break;
        else if(line[0] == 'D')
        {
            stringstream ss(line);
            string item;
            ss>>item;
            ss>>item;
            int index  = ID(item);
            string item1;
            while(ss>>item1)
            {
                int index1 = ID(item1);
                dep[index].push_back(index1);//dep表示受谁的支持
                dep2[index1].push_back(index);//dep2表示支持谁
            }
//print_relation();
        }
        else
        {
            stringstream ss(line);
            string item;
            ss>>item;
            ss>>item;
            int index = ID(item);//
            if(line[0] == 'I')
            {
                if(status[index])
                    cout<<"   "<<ID_name[index]<<" is already installed."<<endl;
                else
                    install(index,2);
            }
            else if(line[0] == 'R') 
            {
                if(!status[index])
                    cout<<"   "<<ID_name[index]<<" is not installed."<<endl;
                else 
                    remove(index,2);
            }
            else
            {
                list_all();
            }
        }
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/TorettoRui/p/10464161.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值