1. 程式人生 > 遊戲攻略 >《戰國無雙5》馬匹養成指南 馬匹選擇什麼技能

《戰國無雙5》馬匹養成指南 馬匹選擇什麼技能

二分圖的題

可以分別以行列和列行建

1.二分圖

#include<bits/stdc++.h>

using namespace std;
const int N=555;

int n,m;
char c[N][N];
int a[N][N],b[N][N];
int flag[N<<5],match[N<<5];
int head[N<<5],nxt[N<<6],to[N<<6];
long long ans;


int _;
void add(int x,int y)
{
    _++;
    to[_]=y;
    nxt[_]
=head[x]; head[x]=_; return ; } bool find(int x) { for(int i=head[x];i;i=nxt[i]) { int y=to[i]; if(!flag[y]) { flag[y]=1; if(!match[y] ||find(match[y]) ) { match[y]=x; return 1; } } }
return 0; } int cnt; int main() { ios::sync_with_stdio(false); cin>>n>>m; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cin>>c[i][j]; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { if(c[i][j]=='#') { cnt
++; continue; } if(j==1) cnt++; a[i][j]=cnt; } } for (int j=1;j<=m;j++) { for (int i=1;i<=n;i++) { if(c[i][j]=='#') { cnt++; continue; } if (i==1) cnt++; b[i][j]=cnt; } } for (int i=1;i<=n;i++) { for (int j=1;j<=m;j++) { if(c[i][j]!='*') continue; add(a[i][j],b[i][j]); } } for(int i=1;i<=cnt;i++) { memset(flag,0,sizeof(flag)); if(find(i)) ans++; } cout<<ans; return 0; }

2.網路流

#include<bits/stdc++.h>

using namespace std;

const int maxn = 90000;

int tot = -1,n,m,cnt1,cnt2,S,T,ans;
int pos1[60][60],pos2[60][60];
int deep[maxn],head[maxn];
char mp[60][60];
queue<int> q;


struct node
{
    int to,net,va;
}data[maxn<<4];

void add(int a,int b,int c)
{
    data[++tot].net = head[a];data[tot].to = b;data[tot].va = c;head[a] = tot;
    data[++tot].net = head[b];data[tot].to = a;data[tot].va = 0;head[b] = tot;
    return ;
}

bool bfs()
{
    memset(deep,0,sizeof(deep));
    while(!q.empty()) q.pop();
    deep[S] = 1;q.push(S);
    
    while(!q.empty())
    {
        int x = q.front();q.pop();
        for(int i=head[x];i!=-1;i=data[i].net)
        {
            int to = data[i].to ;
            int va = data[i].va ;
            if(va&&!deep[to])
            {
                deep[to] = deep[x] + 1;
                q.push(to);
                if(to==T) return true;
            }
        }
    }
    
    return false;
}

int dfs(int x,int flow)
{
    if(x==T) return flow;
    int rest = flow;
    for(int i=head[x];i!=-1;i=data[i].net)
    {
        int to=data[i].to ;
        int va=data[i].va ;
        if(va&&deep[to]==deep[x]+1)
        {
            int k=dfs(to,min(rest,va));
            if(!k) 
            deep[to]=0;
            data[i].va-=k;data[i^1].va+=k;
            rest-=k;
        }
        
        if(!rest) return flow;
    }
    return flow-rest;
}

int main()
{
    memset(head,-1,sizeof(head));
    cin>>n>>m;
    
    S = n * m + 1;T = n * m + 2;
    for(int i=1;i<=n;i++) 
    scanf("%s",mp[i]+1);
    for(int i=1;i<=n;i++)
    {
        cnt1++;
        for(int j=1;j<=m;j++)
        {
            if(mp[i][j]=='#') cnt1++;
            else pos1[i][j]=cnt1;
        }
    }
    for(int j=1;j<=m;j++)
    {
        cnt2++;
        for(int i=1;i<=n;i++)
        {
            if(mp[i][j]=='#') cnt2++;
            else pos2[i][j]=cnt2;
        }
    }
    for(int i=1;i<=cnt1;i++) 
    add(S,i,1);
    for(int i=1;i<=cnt2;i++) 
    add(cnt1+i,T,1);
    
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            if(mp[i][j]=='*')
                add(pos1[i][j],pos2[i][j]+cnt1,1);
    while(bfs()) ans += dfs(S,2e9);
    cout<<ans;
    return 0;
}