跳到正文

CSP202605C. 死锁优化

#include<bits/stdc++.h>
using namespace std;
#define mm(a,b) memset(a,b,sizeof(a))
#define int long long
#define endl "\n"
#define ios ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define pb push_back
const int N=1e5+10;
const int inf=0x3f3f3f3f;
int n,m;
//进程
struct jincheng
{
    int id;//编号
    char type;//类型
    int st,k,w=0;//属性
    vector<pair<int,int>>task;//任务
    set<int> rs;//当前实际持有的资源
    int remain= 0;//当前任务还需要运行多少段
    bool giveup=false;// 是否在本段末释放全部资源(A类)
    int fails=0;//失败次数
    int order=1;//第几个任务
    bool working=false;//运行
    bool finishing=false;//结束
    int value=0;//收益
    int time=0;//运行时间

};

//资源
struct ziyuan
{
    int id;//编号
    int owner=0;//使用者
    set<int>app;//申请者
};

int max_st;//最大段
vector<jincheng>jc;//进程
vector<ziyuan>zy;//资源
set<int>pool;//进程池
int cnt;//时间

//执行当前任务,即初始化进程
void kaishi(int id){
    auto &p=jc[id];
    p.working=true;
    p.remain=p.task[p.order].second;
    p.fails=0;
}

//分配和抢夺,即修改资源拥有者并把其id放入对应进程资源库
void fenpei(int x,int id){
    int old=zy[x].owner;
    if(old!=0){
        jc[old].rs.erase(x);
    }
    zy[x].owner=id;
    jc[id].rs.insert(x);
}

//释放资源,即初始化该进程占有资源
void shifang(int id){
    for(int x:jc[id].rs)zy[x].owner=0;
    jc[id].rs.clear();
}

//唤醒当前时刻开始进程,即放入线程池
void huanxing(){
    for(int i=1;i<=n;i++){
        if(jc[i].st==cnt)pool.insert(i);
    }
}
//操作申请
void shenqing(){
    for(int i=1;i<=m;i++)zy[i].app.clear();
    //收集当前时刻全部申请
    for(int id:pool){
        auto &p=jc[id];
        if(!p.working) {
            int x=p.task[p.order].first;
            zy[x].app.insert(id);
        }
    }
    //每种资源处理
    for(int i=1;i<=m;i++){
        auto &app=zy[i].app;
        if(app.empty())continue;
        int winner=0;
        // C类:此前已经失败w次,本段发动强抢
        for(int id:app){
            auto &p=jc[id];
            if(p.type=='C'&&p.fails>=p.w) {
                winner=max(winner, id);
            }
        }
        if(winner!=0){
            //最大编号的强抢者实际获得资源
            fenpei(i, winner);
            //所有强抢者都会进入任务运行状态
            for(int id:app){
                auto &p=jc[id];
                if(p.type=='C'&&p.fails>=p.w)kaishi(id);
            }
        }else if(zy[i].owner==0){//没有强抢且资源空闲:最小编号申请成功
            int id=*app.begin();
            fenpei(i,id);
            kaishi(id);
        }
        //尚未进入运行状态的申请者,本段申请失败
        for(int id:app) {
            auto &p=jc[id];
            if(p.working)continue;
            p.fails++;
            if(p.type=='A'&&p.fails==p.w)p.giveup=true;//必须等段末再释放
            if(p.type=='B'&&p.fails==p.w)kaishi(id);// 本段直接开始任务,但没有得到资源
        }
    }
}
//操作执行
void work(){
    for(int id:pool){
        auto &p=jc[id];
        p.time++;
        if(p.working){
            p.value+=(int)p.rs.size();
            p.remain--;
        }
    }
}
//操作释放
void realse(){
    vector<int>finished;
    for(int id:pool){
        auto &p=jc[id];
        //A类本段达到忍耐限度,段末释放
        if(p.giveup){
            shifang(id);
            p.giveup=false;
        }
        // 当前任务尚未完成,或者仍在等待
        if(!p.working||p.remain!=0)continue;
        p.working=false;
        p.order++;
        p.fails=0;
        if(p.order>p.k){
            p.finishing=true;
            shifang(id);
            finished.pb(id);
        }
    }
    for(int id:finished)pool.erase(id);
}
bool deadlock() {
    // 还有进程未来才启动
    if(cnt<max_st)return false;
    for(int id:pool){
        auto &p=jc[id];
        // 有任务正在运行,之后仍会推进
        if(p.working)return false;
        int x=p.task[p.order].first;
        // 所需资源空闲,下一段会有人申请成功
        if(zy[x].owner==0)return false;
        // B、C类迟早会开始任务
        if(p.type=='B'||p.type=='C')return false;
        // A类尚未达到忍耐限度,而且还持有资源:
        // 未来释放资源,可能改变局面
        if(p.type=='A'&&p.fails<p.w &&!p.rs.empty())return false;
    }
    return true;
}
void solve() {
    cin>>n>>m;
    //初始化
    jc.clear();
    jc.resize(n+1);
    zy.clear();
    zy.resize(m+1);
    pool.clear();
    max_st=0;
    for(int i=1;i<=n;i++){
        auto &p=jc[i];
        p.id=i;
        cin>>p.type;
        if(p.type=='X')cin>>p.st>>p.k;
        else cin>>p.st>>p.w>>p.k;
        p.task.resize(p.k+1);
        for(int j=1;j<=p.k;j++)cin>>p.task[j].first>>p.task[j].second;
        max_st=max(max_st,p.st);
    }
    for(int i=1;i<=m;i++)zy[i].id=i;
    cnt=0;

    //根据时刻每一时刻来进行资源分配和执行
    while(cnt<max_st||!pool.empty()){
        cnt++;
        huanxing();
        shenqing();
        work();
        realse();
        if(!pool.empty()&&deadlock())break;
    }
    for(int i=1;i<=n;i++){
        cout<<jc[i].value<<' ';
        if(jc[i].finishing)cout<<jc[i].time<<endl;
        else cout<<-1<<endl;
    }
}

signed main(){
    ios;
    int T=1;//cin>>T;
    while(T--)solve();
    return 0;
}
posted @ 2026-09-11 19:38  尔一  阅读(15)  评论(0)    收藏  举报