首页 > 其他分享 >UVA753 A Plug for UNIX 题解

UVA753 A Plug for UNIX 题解

时间:2023-12-06 20:35:12浏览次数:45  
标签:Plug ch return int 题解 flow UNIX maxn mp

Link

UVA753 A Plug for UNIX

Question

有 \(n\) 个插座,\(m\) 个设备和 \(k\) 种转换器,每种转换器有无限多个。转换器可以插着转换器用,每个插座或插头的类型可能不同,求最少剩多少个不匹配的设备

Sulotion

先考虑转换器连用的情况,用边表 \(G[x][y]\) 表示 \(x\) 类型可以转换成 \(y\) 类型,用 Floyd 刷出所有的情况

然后把问题转换成网络流,从起点 \(s\) 到 \(m\) 个设备建一条 容量为 \(1\) 的边,从 \(n\) 个插座到 \(t\) 建立一条容量为 \(1\) 的边,对 \(G[x][y]=1\) 的节点 \(x,y\) 建立一条容量为 无线的 边,可以可以匹配的设备数量就是最大流

Code

#include<bits/stdc++.h>
using namespace std;
int N,M,K;
const int maxn=405,INF=1<<29;
bool G[maxn][maxn];
int cnt;
map<string,int> mp;

inline int read(){
    int ret=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();}
    while(ch<='9'&&ch>='0')ret=ret*10+ch-'0',ch=getchar();
    return ret*f;
}

int get(string x){
    if(mp.find(x)==mp.end())
        mp[x]=++cnt;
    return mp[x];
}

struct Edge{
    int from,to,cap,flow;
    Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f){}
};

struct Dinic{
    int n,m,s,t;
    vector<Edge> edges;
    vector<int> G[maxn];
    bool vis[maxn];
    int d[maxn];
    int cur[maxn];

    void init(int n){
        this->n=n;
        for(int i=1;i<=n;i++) G[i].clear();
        edges.clear();
    }

    void add_e(int from,int to,int cap){
        // printf("%d %d %d\n",from,to,cap);
        edges.push_back(Edge(from,to,cap,0));
        edges.push_back(Edge(to,from,0,0));
        m=edges.size();
        G[from].push_back(m-2);
        G[to].push_back(m-1);
    }
    
    bool BFS(){
        memset(vis,0,sizeof vis);
        queue<int> Q;
        Q.push(s);d[s]=0;vis[s]=1;
        while(!Q.empty()){
            int x=Q.front();Q.pop();
            for(int i=0;i<G[x].size();i++){
                Edge &e=edges[G[x][i]];
                if(!vis[e.to]&&e.cap>e.flow){
                    vis[e.to]=1;
                    d[e.to]=d[x]+1;
                    Q.push(e.to);
                }
            }
        }
        return vis[t]; //判断是否能走到 t
    }

    int DFS(int x,int a){ //a表示当前流到这个节点的流
        if(x==t||a==0) return a;
        int flow=0,f;
        for(int& i=cur[x];i<G[x].size();i++){ //当前弧优化
            Edge& e=edges[G[x][i]];
            if(d[x]+1==d[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0){
                e.flow+=f;
                edges[G[x][i]^1].flow-=f;
                flow+=f;
                a-=f;
                if(a==0)break;
            }
        }
        return flow;
    }

    int Maxflow(int s,int t){
        this->s=s,this->t=t;
        int flow=0;
        while(BFS()){
            memset(cur,0,sizeof cur);
            flow+=DFS(s,INF);
        }
        return flow;
    }
};

void solve(){
    mp.clear();cnt=0;
    N=read();
    vector<int> A(N+1);
    for(int i=1;i<=N;i++){
        string now;cin>>now;A[i]=get(now);
    }
    M=read();
    vector<int> B(M+1);
    for(int i=1;i<=M;i++){
        string now;cin>>now;cin>>now;B[i]=get(now);
    }
    memset(G,0,sizeof G);
    K=read();
    for(int i=1;i<=K;i++){
        string X,Y;
        cin>>X>>Y;
        G[get(X)][get(Y)]=1;
    }

    for(int k=1;k<=cnt;k++)
    for(int i=1;i<=cnt;i++)
    for(int j=1;j<=cnt;j++){
        G[i][j]|=(G[i][k]&G[k][j]);
    }

    Dinic F;
    F.init(cnt+2);
    int st=cnt+1,en=cnt+2;
    for(int i=1;i<=M;i++)
        F.add_e(st,B[i],1);
    for(int i=1;i<=N;i++)
        F.add_e(A[i],en,1);
    for(int i=1;i<=N;i++)
    for(int j=1;j<=M;j++){
        if(A[i]==B[j]) continue;
        if(G[B[j]][A[i]]){
            F.add_e(B[j],A[i],INF);
        }
    }
    
    cout<<M-F.Maxflow(st,en);

}
int main(){
    int T=read();
    while(T--){
        solve();
        if(T) printf("\n\n");
    }
    printf("\n");
    return 0;
}

标签:Plug,ch,return,int,题解,flow,UNIX,maxn,mp
From: https://www.cnblogs.com/martian148/p/17880459.html

相关文章

  • UVA1395 Slim Span 题解
    LinkUVA1395SlimSpanQuestion求所有生成树中最大边权与最小边权差最小的,输出他们的差值Solution因为\(n\le100\)非常小,先把边从小到大排序,那么生成树的边肯定是排序后上的边连续的一块所以,可以枚举连续一块的起点\(L\),\(R\)从\(L\)往后推,判断全图连通性,如果已经完......
  • CF1809D Binary String Sorting 题解
    题意:思路:贪心:单调不降的$01$字符串,一定是一串连续的$0$再加上一串连续的$1$。由于每次操作的代价很大,所以需要在操作次数尽可能少的情况下,尽可能多地使用交换操作。由于$1$次交换操作,只能减少$1$个逆序对,当存在多个逆序对时,优先通过删除操作减少逆序对的......
  • ucup hefei 题解
    比赛链接B很有意思的题首先题目的要求为可以拆分成\(2\)个不相交的不降子序列根据\(dilworth\)定理,最小链覆盖\(=\)最长反链,所以要求最长反链\(\le2\)即原序列的逆序列的最长不降子序列长度\(\le2\)不难得到一个\(dp\)做法为:令\(f_{i,j}\)为到数\(i\),最长上......
  • python HTML文件标题解析问题的挑战
    引言在网络爬虫中,HTML文件标题解析扮演着至关重要的角色。正确地解析HTML文件标题可以帮助爬虫准确地获取所需信息,但是在实际操作中,我们常常会面临一些挑战和问题。本文将探讨在Scrapy中解析HTML文件标题时可能遇到的问题,并提供解决方案。问题背景在解析HTML文件标题的过程中,......
  • Error: error:0308010C:digital envelope routines::unsupported 【问题解决】【转载
    原文链接:  https://www.cnblogs.com/jaxu/p/17171211.html今天早上打开电脑,更新了日常工作的github仓库,然后就是习惯性地执行了"npminstall",发现报了下面这个错误:Error:error:0308010C:digitalenveloperoutines::unsupported顺便看了一下错误堆栈,发现是一个Node......
  • 线性代数题解
    前言写完了这道题我好想刚明白一点最小割???UU好闪,拜谢UU。题解首先,我们可以发现若第\(i\)行的\(B\)没选,那么第\(i\)列的\(B\)也不选,所以此时对于行和列是等价的。若\(A_i\)是\(0\),则会减少贡献\(\sum_{j}B_{i,j}\)。否则会减少贡献\(C_i\)。当\(A_i\)是\(0\)......
  • CF603题解
    CF603CodeforcesRound334(Div.1)CF603AlinkCF603A题意现有一个长度为\(n\)的01串,可以进行一次区间翻转(起点终点随意,并且区间里的值1变0,0变1),得到一个新的01串,使得得到的新的01串中的一个子串最长(子串不一定连续),且这个子串是01间隔的,没......
  • CF1824B1 LuoTianyi and the Floating Islands (Easy Version) 题解
    题意:思路:由于$k∈[1,3]$,分类讨论:当$k=1$时,有人结点自身即为好结点,每种情况的期望为$\frac{1}{n}$,$n$种情况的期望和为$1$。最终答案即为$1$。当$k=2$时,$2$个有人结点之间的路径上的结点即为好结点,那么问题转化为:树上所有路径的结点......
  • ABC325G offence 题解
    给出一个长为\(n\)的字符串和非负整数\(k\)。你可以进行以下操作若干次,使得最终字符串长度最小。选择一个字串of。然后删掉of以及这之后的\(i\)个字符。\(i\)由你决定,但要满足\(0\leqi\leqk\)。输出这个最小长度。\(1\leqn,k\leq300\)。做完以后感觉很简单。但......
  • CTFpwn格式化字符串两种应用及2023ISCTF的fmt题解wp
    三个例子的引入目前我遇到的格式化字符串漏洞(formatstring,后文简称fmt)主要存在于printf函数,本文也就以printf举例。例一,标准格式的printf read(0,buf,33);printf("%s",buf);例二,占位符与变量 printf("%d%c%s",a,b,c);//%d%c%s会访问变量以输出整型,字符等。其中a,b,c为三......