POJ 1087 A Plug for UNIX (네트워크 흐름 의 최대 흐름)

제목: POJ 1087
누가 이 문 제 를 2 점 최대 일치 하 는 주제 로 만 들 었 는 지 모르겠다.그래서 별로 생각 하지 않 고 이분 도 모형 대로 만 들 었 어 요.나중에 2 점 의 최대 일치 가 분명히 안 되 는 것 을 발견 했다.가치 가 있다.그냥 최대 흐름 으로 오 면 얼마나 편 한데.그리고 계속 WA.나중에 곰 곰 이 생각해 보니까이 건 2 분 도 를 만 들 수 없 잖 아...이 문 제 는 이분 도와 아무런 관계 가 없다...
이 문제 의 건설 방향 은 원점 과 모든 설비 의 콘센트 유형 을 연결 시 켜 어 셈 블 리 점 과 모든 콘센트 를 연결 시 키 는 것 이다.그리고 플 로 이 드 로 이 장치 가 꽂 을 수 있 는 콘센트 로 전환 할 수 있 는 지 판단 한다.변환 할 수 있 는 것 만 있 으 면 연 결 된 것 이 고, 가중치 는 INF 이다.그리고 최대 흐름 을 한 번 구하 고 n 으로 빼 면 됩 니 다.
이 문 제 는 입력 한 콘센트 가 중 복 될 수 있다 는 구덩이 가 있다.무 거 워 야 돼.
코드 는 다음 과 같 습 니 다:
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <queue>
#include <map>
#include <set>
#include <algorithm>

using namespace std;
const int INF=0x3f3f3f3f;
int m, plug[1100], dp[1100][1100];
int head[1100], source, sink, nv, cnt, n, tot, tt;
int num[1100], d[1100], pre[1100], cur[1100];
struct node
{
    int u, v, cap, next;
} edge[1000000];
void add(int u, int v, int cap)
{
    edge[cnt].v=v;
    edge[cnt].cap=cap;
    edge[cnt].next=head[u];
    head[u]=cnt++;

    edge[cnt].v=u;
    edge[cnt].cap=0;
    edge[cnt].next=head[v];
    head[v]=cnt++;
}
void bfs()
{
    memset(d,-1,sizeof(d));
    memset(num,0,sizeof(num));
    queue<int>q;
    q.push(sink);
    d[sink]=0;
    num[0]=1;
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        for(int i=head[u]; i!=-1; i=edge[i].next)
        {
            int v=edge[i].v;
            if(d[v]==-1)
            {
                d[v]=d[u]+1;
                num[d[v]]++;
                q.push(v);
            }
        }
    }
}
void isap()
{
    memcpy(cur,head,sizeof(cur));
    bfs();
    int flow=0, u=pre[source]=source, i;
    while(d[source]<nv)
    {
        if(u==sink)
        {
            int f=INF, pos;
            for(i=source; i!=sink; i=edge[cur[i]].v)
            {
                if(f>edge[cur[i]].cap)
                {
                    f=edge[cur[i]].cap;
                    pos=i;
                }
            }
            for(i=source; i!=sink; i=edge[cur[i]].v)
            {
                edge[cur[i]].cap-=f;
                edge[cur[i]^1].cap+=f;
            }
            flow+=f;
            u=pos;
        }
        for(i=cur[u]; i!=-1; i=edge[i].next)
        {
            if(d[edge[i].v]+1==d[u]&&edge[i].cap) break;
        }
        if(i!=-1)
        {
            cur[u]=i;
            pre[edge[i].v]=u;
            u=edge[i].v;
        }
        else
        {
            if(--num[d[u]]==0) break;
            int mind=nv;
            for(i=head[u]; i!=-1; i=edge[i].next)
            {
                if(mind>d[edge[i].v]&&edge[i].cap)
                {
                    mind=d[edge[i].v];
                    cur[u]=i;
                }
            }
            d[u]=mind+1;
            num[d[u]]++;
            u=pre[u];
        }
    }
    printf("%d
",n-flow); } void floyd() { int i, j, k; for(k=1; k<=tot; k++) { for(i=1; i<=tot; i++) { for(j=1; j<=tot; j++) { dp[i][j]=min(dp[i][k]+dp[k][j],dp[i][j]); } } } } int main() { int i, k, j; tot=0; tt=0; char s[30], s1[30]; map<string,int>q; scanf("%d",&m); memset(head,-1,sizeof(head)); cnt=0; for(i=1; i<=m; i++) { scanf("%s",s); if(!q[s]) q[s]=++tt; } tot=tt; scanf("%d",&n); for(i=1; i<=n; i++) { scanf("%s%s",s,s1); if(!q[s1]) q[s1]=++tot; plug[i]=q[s1]; } memset(dp,INF,sizeof(dp)); scanf("%d",&k); while(k--) { scanf("%s%s",s,s1); if(!q[s1]) q[s1]=++tot; if(!q[s]) q[s]=++tot; dp[q[s]][q[s1]]=1; //printf("--%d %d
",q[s],q[s1]); } floyd(); /*for(i=1;i<=m;i++) { for(j=1;j<=m;j++) { printf("%d ",dp[i][j]); } printf("
"); }*/ source=0; sink=tot+1; nv=sink+1; for(i=1; i<=n; i++) { add(source,plug[i],1); //printf("source--%d
",plug[i]); for(j=1; j<=tt; j++) { if(dp[plug[i]][j]!=INF) { add(plug[i],j,INF); //printf("%d %d
",plug[i],j); } } } for(i=1; i<=tt; i++) { add(i,sink,1); } //printf("%d %d
",n,m); isap(); return 0; }

좋은 웹페이지 즐겨찾기