• Exclusive Access 2 UVA


    大致题意:给定n个进程和它所需的两个资源,对于每个进程,让你确定它的调用两个资源的先后顺序,使得所有进程的总时间最短

    (因为进程是可以并行的,比如“先P后Q”的进程和“先P后R”的进程可以并行,但“先P后Q”的进程和“先Q后R”的进程却不能

    等待链:等待链是一个局部概念,表示所有约束的一部分组成的有向链,如R0->R1->R2表示资源R0完成后,才能完成R1,然后是R2

    题解:关键是理解题目中等待链的概念。把每个进程看成无向边,连接它的两个资源;现在要把无向边定向,使最长等待链最短。

    问题转化为,给定一个无向图,让你给边定向,使最长链最短。

    图形结构不好做,还是要转化为树形结构。做了一个整体性的转化:把结点分成p层,从左到右编号0,1,2...,使得同层结点之间没有边。对任意一条边u-v,定向“从小编号到大编号”

    然后就是“结点分层的问题”,可以参考“图的染色”问题的做法

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    
    using namespace std;
    
    const int N=100+5,C=15,all=1<<15;
    
    int n;
    int a1[N],a2[N];
    bool g[C][C];
    
    int f[all];
    int pre[all];
    bool ok[all];
    
    int pos[C];
    
    int main()
    {
        while(cin>>n){
            memset(g,0,sizeof g);
            char a,b;
            for(int i=1;i<=n;i++){
                cin>>a>>b;
                a1[i]=a-'L';
                a2[i]=b-'L';
                g[a1[i]][a2[i]]=g[a2[i]][a1[i]]=1;
            }        
            memset(ok,0,sizeof ok);
            bool fail;
            for(int s=0;s<all;s++)
            {
                fail=0;
                for(int i=0;i<15&&!fail;i++)if(s&(1<<i))
                    for(int j=i+1;j<15&&!fail;j++)if(s&(1<<j))
                        if(g[i][j])
                            fail=1;
                ok[s]=fail?0:1;
            }
            
            memset(f,0x3f,sizeof f);
            f[0]=0;
            for(int s=1;s<all;s++)
            {
                for(int s0=s&(s-1);s0;s0=s&(s0-1))
                    if(ok[s^s0])
                        if(f[s]>f[s0]+1)
                        {
                            f[s]=f[s0]+1;
                            pre[s]=s0;
                        }
                if(ok[s])
                    if(f[s]>f[0]+1)
                    {
                        f[s]=f[0]+1;
                        pre[s]=0;
                    }     
            }
            printf("%d
    ",f[all-1]-2);
            int p=f[all-1];
            for(int s=all-1;s;s=pre[s])
            {
                for(int i=0;i<15;i++)
                    if((s^pre[s])&(1<<i))
                        pos[i]=p;
                p--;
            }
            for(int i=1;i<=n;i++)
            {
                if(pos[a1[i]]<pos[a2[i]])
                    printf("%c %c
    ",a1[i]+'L',a2[i]+'L');
                else 
                    printf("%c %c
    ",a2[i]+'L',a1[i]+'L');
            }
        }
        return 0;
    }
  • 相关阅读:
    作业3
    数组求和
    2.自己的Github试用过程
    2.自己的Github注册流程
    图片左右滑动整理为插件
    artDialog中的time参数,ajax请求中的异步与同步
    简单的图片放大镜效果插件
    3月份学习安排
    前端好的网站
    web app开发中遇到的问题
  • 原文地址:https://www.cnblogs.com/mgnfcnt/p/9263549.html
Copyright © 2020-2023  润新知