思路
这个题目当时在考试中其实思路是正确的,即队列+递归处理,当时是站在图的角度考虑。但由于在考试中边界部分出了问题,这题只得了0分。然后写了个纯模拟不优化,超时(60分),因为这时候复杂度是O(8*n^2)
主要问题
判断死锁的逻辑:
1. 当前需要匹配的进程队列已空(存在a到b的弧,没有b到a的弧),必然不可匹配
2. 存在环,即递归到达同一进程的次数超过进程总数
递归逻辑
- 队头目标节点队列已空,死锁,返回
- 若当前队头能匹配,消除,计数不递增,进入目标节点
- 当前队头不能匹配,计数递增,进入目标节点
因为图不一定是全连通的,外面得套一层循环调用。这时候时间复杂度是O(8n)
如果在循环内创建队列时间也会高,创个全局的list可以clear。
#include <bits/stdc++.h>
using namespace std;
const int MAX =10000+4;
struct process{
bool send = false;
int dst;
};
int T,n;
bool DeadLock = false;
list<process> q[MAX];
void dfs(int u,int cnt){
if(DeadLock)
return;
if(cnt > n){
DeadLock = true;
return;
}
while(!q[u].empty() && !DeadLock){
process v = q[u].front();
if(q[v.dst].empty()){
DeadLock = true;
return;
}
else if(q[v.dst].front().dst == u && (v.send!=q[v.dst].front().send)){
q[v.dst].pop_front();
q[u].pop_front();
dfs(v.dst,cnt);
}
else
dfs(v.dst,cnt+1);
}
}
int main(){
cin >> T >> n;getchar();
for(int i = 0; i < T; i++){
for(int j = 0; j < n; j++){
q[j].clear();
string line;
getline(cin,line);
stringstream ss(line);
string s;
while(ss >> s){
process p;
p.dst = stoi(s.substr(1));
if(s[0] == 'R')
p.send = false;
else
p.send = true;
q[j].push_back(p);
}
}
DeadLock = false;
for(int k = 0 ; k < n;k++)
dfs(k,0);
cout << DeadLock <<endl;
}
}