poj3866 Exclusive Access 2

来源:互联网 发布:东宫番外清风知我意 编辑:程序博客网 时间:2024/06/08 17:18

Description Having studied mutual exclusion protocols in the previous
year’s competition you are now facing a more challenging problem. You
have a big enterprise system with a number concurrently running
processes. The system has several resources - databases, message
queues, etc. Each concurrent process works with two resources at a
time. For example, one process might copy a job from a particular
database into the message queue, the other process might take a job
from the message queue, perform the job, and then put the result into
some other message queue, etc. All resources are protected from
concurrent access by mutual exclusion protocols also known as locks.
For example, to access a particular database process acquires the lock
for this database, then performs its work, then releases the lock. No
two processes can hold the same lock at the same time (that is the
property of mutual exclusion). Thus, the process that tries to acquire
a lock waits if that lock is taken by some other process. The main
loop of the process that works with resources P and Q looks like this:

loop forever

  DoSomeNonCriticalWork()  P.lock()  Q.lock()  WorkWithResourcesPandQ()  Q.unlock()  P.unlock()

end loop

The order in which locks for resources P and Q are taken is important.
Consider a case where process c had acquired lock P with P.lock() and
is waiting for lock Q in Q.lock(). It means that lock Q is taken by
some other process d. If the process d is working (not waiting), then
we say that there is a wait chain of length 1. If d had acquired lock
Q and is waiting for another lock R, which is acquired by a working
process e, then we say that there is a wait chain of length 2, etc. If
any process in this wait chain waits for lock P that is already taken
by process c, then we say that the wait chain has infinite length and
the system deadlocks. For this problem, we are interested only in
alternating wait chains where processes hold their first locks and
wait for the second ones. Formally:

Alternating wait chain of length n (n >= 0) is an alternating sequence
of resources Ri (0 <= i <= n + 1) and distinct processes ci (0 <= i <=
n): R0 c0 R1 c1 … Rn cn Rn+1, where process ci acquires locks for
resources Ri and Ri+1 in this order. Alternating wait chain is a
deadlock when R0 = Rn+1.

You are given a set of resources each process works with. Your task is
to decide the order in which each process has to acquire its resource
locks, so that the system never deadlocks and the maximum length of
any possible alternating wait chain is minimized.

Input The first line of the input file contains a single integer n (1
<= n <= 100) - the number of processes. The following n lines describe
resources that each process needs. Each resource is designated with an
uppercase English letter from L to Z, so there are at most 15
resources. Each line describing process contains two different
resources separated by a space.

Output On first line of the output file write a singe integer number m
- the minimally possible length of the maximal alternating wait chain. Then write n lines - one line per process. On each line write two
resources in the order they should be taken by the corresponding
process to ensure this minimal length of the maximal alternating wait
chain. Separate resources on a line by a space. If there are multiple
satisfying orderings, then write any of them. The order of the
processes in the output should correspond to their order in the input.

题目描述比较绕,具体来说就是安排每个任务使用两个资源的顺序,使得在最坏情况下,当要执行一个工作时,需要等待的时间最短。
把资源看成点,任务看成无向边,任务就是把无向边定向,使图中不存在环而且最长链最短。
根据Dilworth定理【参见这里】,把点分成m部分,使每一部分内部没有边。m的最小值就是最长链的最小值。
状压dp即可求解图的着色问题。

#include<cstdio>#include<cstring>#include<algorithm>#include<map>#include<vector>using namespace std;map<char,int> mp;map<int,char> cv;int n,m;bool ok[1<<20],g[20][20];int dp[1<<20],q1[110],q2[110],pre[1<<20],num[20];int main(){    int i,j,k,u,v,clo;    char s1[5],s2[5];    scanf("%d",&m);    for (i=1;i<=m;i++)    {        scanf("%s%s",s1,s2);        if (!mp.count(s1[0])) cv[n]=s1[0],mp[s1[0]]=n++;        if (!mp.count(s2[0])) cv[n]=s2[0],mp[s2[0]]=n++;        u=mp[s1[0]];        v=mp[s2[0]];        q1[i]=u;        q2[i]=v;        g[u][v]=g[v][u]=1;    }    ok[0]=1;    for (i=1;i<(1<<n);i++)    {        ok[i]=1;        for (j=0;j<n;j++)          if (i&(1<<j))          {            if (!ok[i^(1<<j)])            {                ok[i]=0;                break;            }            for (k=0;k<n;k++)              if (j!=k&&(i&(1<<k))&&g[j][k])              {                ok[i]=0;                break;              }            break;          }    }    memset(dp,0x3f,sizeof(dp));    dp[0]=0;    for (i=1;i<(1<<n);i++)      for (j=i;j;j=i&(j-1))        if (ok[j]&&dp[i^j]+1<dp[i])        {            dp[i]=dp[i^j]+1;            pre[i]=j;        }    printf("%d\n",dp[(1<<n)-1]-2);    for (i=(1<<n)-1,clo=1;i;i^=pre[i],clo++)    {        for (j=0;j<n;j++)          if ((1<<j)&pre[i])            num[j]=clo;    }    for (i=1;i<=m;i++)      if (num[q1[i]]<num[q2[i]])        printf("%c %c\n",cv[q1[i]],cv[q2[i]]);      else        printf("%c %c\n",cv[q2[i]],cv[q1[i]]);}
0 0
原创粉丝点击