C - A Plug for UNIX (又是建图坑)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Let_life_stop/article/details/83212062

题目链接:https://cn.vjudge.net/contest/68128#problem/C

没理解好题意真的麻烦,一上午就这么过去了。。。。。

具体思路:按照 源点 ->插座->转换器->插头->汇点的方式建图,源点到插座的流量为1,插头到汇点的流量为1,转换器之间如果能相连则赋值为inf.(转换器相连的条件,对于某一个转换器 他可以连下一个的头或者尾,但是这个转换器的方向不能变!!!坑点)

AC代码:

#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<set>
#include<queue>
#include<stdio.h>
#include<stack>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
# define inf 0x3f3f3f3f
# define maxn 500+10
# define ll long long
int n,m,k;
int dis[maxn][maxn];
char chazuo[maxn][maxn];
char change[maxn][maxn];
char chahead[maxn][maxn];
int vis[maxn],pre[maxn];
struct node
{
    char fr[maxn];
    char to[maxn];
} a[maxn];

bool bfs(int st,int ed)
{
    queue<int>q;
    memset(vis,0,sizeof(vis));
    vis[st]=1;
    pre[st]=st;
    q.push(st);
    while(!q.empty())
    {
        int top=q.front();
        q.pop();
        for(int i=1; i<=n+m+k+2; i++)
        {
            if(vis[i]==0&&dis[top][i]>0)
            {
                pre[i]=top;
                vis[i]=1;
                if(i==ed)return true;
                q.push(i);
            }
        }
    }
    return false;
}
int EK(int st,int ed)
{
    int ans=0;
    while(bfs(st,ed))
    {
        int minn=inf;
        for(int i=ed; i!=st; i=pre[i])
        {
            minn=min(minn,dis[pre[i]][i]);
        }
        for(int i=ed; i!=st; i=pre[i])
        {
            dis[pre[i]][i]-=minn;
            dis[i][pre[i]]+=minn;
        }
        ans+=minn;
    }
    return ans;
}
int main()
{
    while(~scanf("%d",&n))
    {
        memset(dis,0,sizeof(dis));
        for(int i=1; i<=n; i++)
        {
            scanf("%s",chazuo[i]);
        }
        scanf("%d",&m);
        for(int i=1; i<=m; i++)
        {
            scanf("%*s %s",chahead[i]);
        }
        scanf("%d",&k);
        for(int i=1; i<=k; i++)
        {
            scanf("%s %s",a[i].fr,a[i].to);
        }
        for(int i=1; i<=n; i++) //zuo -> chahead
        {
            for(int j=1; j<=m; j++)
            {
                if(strcmp(chazuo[i],chahead[j])==0)
                {
                    dis[i][n+k+j]=1;
                }
            }
        }
        for(int i=1; i<=n; i++) //zuo -> change
        {
            for(int j=1; j<=k; j++)
            {
                if(strcmp(chazuo[i],a[j].fr)==0||strcmp(chazuo[i],a[j].to)==0)
                {
                    dis[i][n+j]=1;
                }
            }
        }
        for(int i=1; i<=k; i++) //change-> head
        {
            for(int j=1; j<=m; j++)
            {
                if(strcmp(a[i].to,chahead[j])==0||strcmp(a[i].fr,chahead[j])==0)
                {
                    dis[n+i][n+k+j]=1;
                }
            }
        }
        for(int i=1; i<=k; i++) // change -> change
        {
            for(int j=1; j<=k; j++)
            {
                if(strcmp(a[i].fr,a[j].to)==0)
                {
                    dis[i+n][j+n]=inf;
                }
            }
        }
        int st=n+m+k+1;
        int ed=st+1;
        for(int i=1; i<=n; i++)
        {
            dis[st][i]=1;
        }
        for(int i=1; i<=m; i++)
        {
            dis[n+k+i][ed]=1;
        }
        int ans=EK(st,ed);
        printf("%d\n",m-ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Let_life_stop/article/details/83212062