arc074F - Leftmost Ball 最小割

8人阅读 评论(0) 收藏 举报
分类:

题解:

今天考试的一道题,当时只拿了70分,后面的TLE了,先来讲一下我的建图方法:
同一行相邻两个非障碍点连流量为inf的边,同一列相邻两个非障碍点连流量为inf的边,这里两次的点是不一样的,也就是说一个非障碍点被拆成了两个点,然后代表同一个非障碍点的两个点间连流量为1的边(以上所有连的边都是双向边),跑最小割即可,点数是2nm,边数是6nm,虽然不是最优解,但也是能过的。但是今天下午调试的时候遇到了一个以前没有遇到的问题:就是建双向边的时候,每条边的反向边的初始流量是与它自己的流量一样的,而我的inf开到了2147483647,所以流量加到负数就GG了,以后要注意啊……

代码:

#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define pa pair<int,int>
const int Maxn=310;
const int inf=0x3f3f3f3f;
int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
    return x*f;
}
int n,m,mp[Maxn][Maxn],st,ed;
int num[Maxn][Maxn],tot=0;
char s[Maxn];
struct Edge{int y,d,next;}e[Maxn*Maxn*6];
int last[Maxn*Maxn<<1],cur[Maxn*Maxn<<1],len=1;

void ins(int x,int y,int d)
{
    int t=++len;
    e[t].y=y;e[t].d=d;
    e[t].next=last[x];last[x]=t;
}
void addedge_2(int x,int y,int d){ins(x,y,d),ins(y,x,d);}
int h[Maxn*Maxn<<1];
bool bfs()
{
    memset(h,0,sizeof(h));h[st]=1;
    static queue<int>q;q.push(st);
    while(!q.empty())
    {
        int x=q.front();q.pop();
        for(int i=last[x];i;i=e[i].next)
        {
            int y=e[i].y;
            if(e[i].d>0&&!h[y])h[y]=h[x]+1,q.push(y);
        }
    }
    return h[ed];
}
int dfs(int x,int f)
{
    if(x==ed)return f;
    int s=0,t;
    for(int i=cur[x];i;i=e[i].next)
    {
        int y=e[i].y;
        if(e[i].d>0&&h[y]==h[x]+1&&s<f)
        {
            cur[x]=i;
            t=dfs(y,min(e[i].d,f-s));
            s+=t;e[i^1].d+=t;e[i].d-=t;
        }
    }
    if(!s)h[x]=0;
    return s;
}
int main()
{
    n=read(),m=read();
    int stx,sty,edx,edy;
    for(int i=1;i<=n;i++)
    {
        scanf("%s",s+1);
        for(int j=1;j<=m;j++)
        {
            if(s[j]=='S')stx=i,sty=j,mp[i][j]=1;
            else if(s[j]=='T')edx=i,edy=j,mp[i][j]=2;
            else if(s[j]=='.')mp[i][j]=3;
            else mp[i][j]=4,num[i][j]=++tot;
        }
    }
    if(stx==edx||sty==edy)return puts("-1"),0;
    st=(tot<<1)+1,ed=(tot<<1)+2;
    for(int i=1;i<=n;i++)
    {
        int t=-1;
        for(int j=1;j<=m;j++)
        if(mp[i][j]!=3)
        {
            if(t!=-1)
            {
                int t1=num[i][t],t2=num[i][j];
                if(mp[i][t]==1)t1=st;
                if(mp[i][t]==2)t1=ed;
                if(mp[i][j]==1)t2=st;
                if(mp[i][j]==2)t2=ed;
                addedge_2(t1,t2,inf);
            }
            t=j;
        }
    }
    for(int j=1;j<=m;j++)
    {
        int t=-1;
        for(int i=1;i<=n;i++)
        if(mp[i][j]!=3)
        {
            if(t!=-1)
            {
                int t1=num[t][j]+tot,t2=num[i][j]+tot;
                if(mp[t][j]==1)t1=st;
                if(mp[t][j]==2)t1=ed;
                if(mp[i][j]==1)t2=st;
                if(mp[i][j]==2)t2=ed;
                addedge_2(t1,t2,inf);
            }
            t=i;
        }
    }
    for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++)
    if(mp[i][j]==4)addedge_2(num[i][j],num[i][j]+tot,1);
    int ans=0;
    while(bfs())
    {
        memcpy(cur,last,sizeof(cur));
        ans+=dfs(st,inf);
    }
    printf("%d",ans);
}
查看评论

【AGC002F】Leftmost Ball DP 数学

题目大意  有nn种颜色的球,每种mm个。现在zjt把这nmnm个球排成一排,然后把每种颜色的最左边的球染成第n+1n+1种颜色。求最终的颜色序列有多少种,对10000000071000000007取...
  • ez_yww
  • ez_yww
  • 2017-10-19 17:54:02
  • 115

【AGC002F】Leftmost Ball 组合

原题走这里又是一道思维难度很大的题,思路很难想到首先,不妨假设颜色1~n依次出现,只要最后把答案乘上n!就可以了并且,如果排列是合法的,那么第i个无色球必然在第i个颜色之前出现那么,问题就转化为了对于...
  • CRTorlonia
  • CRTorlonia
  • 2018-02-22 16:50:22
  • 68

AtCoder Grand Contest 002 F - Leftmost Ball 动态规划

题意 有n种颜色,每种颜色有恰好k个小球。现在把这n*k个小球排成一排,然后把每种颜色最左边的小球染成颜色0。问总共有多少种不同的颜色序列。 n,k&amp;lt;=2000 分析 我们可...
  • qq_33229466
  • qq_33229466
  • 2018-02-11 15:15:19
  • 103

[AtCoder AGC002 F][DP]Leftmost Ball

观察发现每个白球后面至少有一种颜色出现k-1次(就是只出现在这个白球后面),知道这个性质后可以从后往前DP把每次放一种颜色的球分成两次,一次放k-1个这种颜色的球,一次放1个白球,这样需要放2*n次f...
  • Coldef
  • Coldef
  • 2017-05-14 11:10:17
  • 1148

[agc002f]Leftmost Ball

前言小清新计数题。题意n种颜色每种颜色有k个球(这n种颜色不含白色),排成一行,把每种颜色第一个球涂成白色。 问颜色序列方案数。DP要求任意后缀0的个数不比颜色种类数多。 不妨设dp表示f[i,j...
  • WerKeyTom_FTD
  • WerKeyTom_FTD
  • 2017-10-26 09:45:44
  • 203

AGC002 F - Leftmost Ball

问题相当于计算有n个颜色0的球,其他n-1种颜色各有m-1个球,一个合法的序列是任意一个前缀中颜色0的球的数量&amp;gt;其他颜色的颜色数量 为了方便计数,我们不妨把每个颜色为0的球和一个颜色捆...
  • L_0_Forever_LF
  • L_0_Forever_LF
  • 2018-04-17 20:57:33
  • 23

[arc074f]Lotus Leaves

题目大意一个池塘,有起点叶子、终点叶子和叶子。 同行同列的叶子联通,问最少删去多少叶子(除起点终点)能使得起点和终点不连通。最小割显然#include #include #define fo(i,a...
  • WerKeyTom_FTD
  • WerKeyTom_FTD
  • 2017-11-06 22:30:10
  • 153

arc074f

题目大意 给你一个n*m网格图,有起点荷叶和终点荷叶,有中转荷叶,其他的格子没东西,一个荷叶可以跳到同一行或者列的另一个荷叶。问最多删掉几个中转荷叶能让起点终点不连通。如果不行输出-1. n,m...
  • Fate_Zero_Saber
  • Fate_Zero_Saber
  • 2018-03-01 17:24:39
  • 20

《深入理解计算机系统》第二章习题2_66

最近打算把《深入理解计算机系统》再看一遍,说实话这本书看多少遍都不嫌多,每一遍都有每一遍的收获。上一次看的时候对于书中每一章后面的习题基本上是略过的,所以这一次着重把这些习题过一遍,然后把比较自认为比...
  • gaohuaid
  • gaohuaid
  • 2015-01-26 17:33:10
  • 2006
    个人资料
    持之以恒
    等级:
    访问量: 4万+
    积分: 3787
    排名: 9878
    最新评论