Description
进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。
由于资源占用是互斥的,当某个进程提出申请资源后,使得有关进程在无外力协助下,永远分配不到必需的资源而无法继续运行,这就产生了死锁。
例如,如果线程A占用了资源1并等待资源2,而线程B占用了资源2并等待资源1,这样两个线程就发生了死锁现象。
为了描述系统资源分配的问题,我们用一张有向图G <v,e>来表示资源分配图。V为有向图的顶点集,包括进程结点集合P={p 1,p 2,…,p n}和资源结点集合R={r 1,r 2,…,r m}两种;E为有向边的集合,其元素包括二元组(p i,r j)或(r j,p i)。(p i,r j)表示进程p i申请资源r j,(r j,p i)表示资源r j被进程p i占用。
根据操作系统中的知识可以知道,如果在一个资源分配图中,从任意一个结点出发,都不存在一条路径能回到自身,则系统中没有死锁,否则系统中可能存在死锁。
你的任务是对于给你的一张资源分配图,判断是否可能存在死锁。
Input
每组数据的第一行是四个整数P,R,E1,E2,其中P表示进程结点数,R表示资源结点数,E1表示(pi,rj)边数,E2表示(rj,pi)边数,1 <= P,R <= 500。接下来E1行每行两个整数pi,rj,表示从结点pi到rj有一条边。接下来E2行每行两个整数rj,pi,表示从结点rj到pi有一条边。0 <= pi < P, 0 <= rj <R。
Output
Sample Input
Sample Output
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const int maxv=1100; int c[maxv]; int G[maxv][maxv]; int topo[maxv],t,n; bool dfs(int u){ c[u]=-1; for(int v=0;v<n;v++){ if(G[u][v]){ if(c[v]<0){ return false; }else if(!c[v]&&!dfs(v)){ return false; } } } c[u]=1; topo[--t]=u; return true; } bool toposort(){ t=n; memset(c,0,sizeof(c)); for(int u=0;u<n;u++) if(!c[u]) if(!dfs(u)) return false; return true; } int main(){ int t,cnt=0; scanf("%d",&t); while(t--){ memset(G,0,sizeof(G)); int P,R,E1,E2; scanf("%d%d%d%d",&P,&R,&E1,&E2); n=P+R; for(int i=0;i<E1;i++){ int tmp,tm; scanf("%d%d",&tmp,&tm); G[tmp][tm+P]=1; } for(int i=0;i<E2;i++){ int tmp,tm; scanf("%d%d",&tmp,&tm); G[tmp+P][tm]=1; } if(toposort()){ printf("Case %d: Impossible\n",++cnt); }else{ printf("Case %d: Possible\n",++cnt); } } return 0; }
2.toposort_bfs:
#include<stdio.h> #include<string.h> #include<queue> #include<vector> #include<algorithm> using namespace std; const int maxv=1100; int G[maxv][maxv]; int indegree[maxv]; int n; queue<int>Q; bool toposort(){ int flag=0; while(!Q.empty()) Q.pop(); for(int i=0;i<n;i++){ if(indegree[i]==0){ Q.push(i); } } if(Q.empty()){ return false; } int tmp; while(!Q.empty()){ tmp=Q.front(); Q.pop(); flag++; for(int i=0;i<n;i++){ if(G[tmp][i]){ indegree[i]--; if(indegree[i]==0){ Q.push(i); } } } } if(flag==n) return true; return false; } int main(){ int t,cnt=0; scanf("%d",&t); while(t--){ memset(indegree,0,sizeof(indegree)); memset(G,0,sizeof(G)); int P,R,E1,E2; scanf("%d%d%d%d",&P,&R,&E1,&E2); n=P+R; for(int i=0;i<E1;i++){ int tmu,tmv; scanf("%d %d",&tmu,&tmv); G[tmu][tmv+P]=1; indegree[tmv+P]++; } for(int i=0;i<E2;i++){ int tmu,tmv; scanf("%d%d",&tmu,&tmv); G[tmu+P][tmv]=1; indegree[tmv]++; } if(toposort()) printf("Case %d: Impossible\n",++cnt); else{ printf("Case %d: Possible\n",++cnt); } } return 0; }
2.并查集
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const int maxv=1100; int fa[maxv]; int Find(int x){ if(x!=fa[x]){ return fa[x]=Find(fa[x]); } return x; } int main(){ int t,n,cnt=0; scanf("%d",&t); while(t--){ int P,R,E1,E2; scanf("%d%d%d%d",&P,&R,&E1,&E2); n=P+R; for(int i=0;i<n;i++) fa[i]=i; int flag=0; for(int i=0;i<E1;i++){ int u,v; scanf("%d%d",&u,&v); u=Find(u); v=Find(v+P); if(u!=v){ u>v?fa[u]=v:fa[v]=u; }else{flag=1;} } for(int i=0;i<E2;i++){ int u,v; scanf("%d%d",&u,&v); u=Find(u+P); v=Find(v); if(u!=v){ u>v?fa[u]=v:fa[v]=u; }else{flag=1;} } if(!flag){ printf("Case %d: Impossible\n",++cnt); }else{ printf("Case %d: Possible\n",++cnt); } } return 0; }
FZU 1924——死锁——————【topo或并查集判环】
原文:http://www.cnblogs.com/chengsheng/p/4358065.html