引水入城

来源:互联网 发布:中国专机767窃听知乎 编辑:程序博客网 时间:2024/04/27 19:19
/*8 7 3 2 2 1 1 (>,不能>=)4 3 2?*//*9 8 7 6 5 4 3 2*/#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#define INF 0x03f3f3f3f using namespace std;int f[505];int n,m,k,ans;int t=0;int a[505][505],ad[505][505];int b[505][505];int movx[5]={0,1,0,0 ,-1};int movy[5]={0,0,-1,1,0};struct node{    int f;    int l,r,c;}v[505];void print(){    cout<<endl;    for(int i=1;i<=n;i++)    {        for(int j=1;j<=m;j++)            printf("%d ",b[i][j]);            cout<<endl;    }    cout<<endl;}bool pd(int x,int y){    if(x<=n && x>=1 && y>=1 && y<=m)    return 1;    else return 0;}//void dfs(int x,int y,int c,int &l,int &r){    int xx,yy;    for(int i=1;i<=4;i++)    {        xx=x+movx[i];//        yy=y+movy[i];        if(b[xx][yy]!=c  && a[xx][yy]<a[x][y] && pd(xx,yy))        {            b[xx][yy]=c;            if(xx==n && yy<l ) l=yy;            if(xx==n && yy>r ) r=yy; //          cout<<c<<" "<<l<<" "<<r<<endl;//          cout<<x<<" "<<y<<" "<<xx<<" "<<yy<<endl;//          cout<<endl;            dfs(xx,yy,c,l,r);        }    }}//bool cmp(node p,node q)//{//  if(p.l <q.l) return 1;//  if(p.l==q.l && p.r<q.r) return 1;//  return 0;//}int main(){    freopen("flow4.in","r",stdin);//  freopen("1.in","r",stdin);//  freopen("flow5self.out","w",stdout);    scanf("%d%d",&n,&m);    for(int i=1;i<=n;i++)        for(int j=1;j<=m;j++)            scanf("%d",&a[i][j]);            int tmpl=0,tmpr=0;    for(int i=1;i<=m;i++)    {        b[1][i]=1;//        dfs(1,i,1,tmpl,tmpr);    }    for(int i=1;i<=m;i++) if(!b[n][i])ans++;    if(ans>0) {printf("%d\n%d\n",0,ans);return 0;}    else{        memset(b,0,sizeof b);        for(int i=1;i<=m;i++) b[1][i]=i;        int ll=INF,lr=0;        for(int i=1;i<=m;i++)        {//          if(a[1][i]<a[1][i+1] || a[1][i]<a[1][i-1]) continue;//////            ll=INF,lr=0;            dfs(1,i,b[1][i],ll,lr);              v[i].f=1,v[i].l=ll,v[i].r=lr,v[i].c=b[n][i];  //开始非要在dfs上做文章,求不同颜色的最小方案,以致很复杂 //          cout<<ll<<" "<<lr<<" "<<b[1][i]<<endl;        }//        print();        //最少线段覆盖        int sl=v[1].l,sr=v[1].r,prec=v[1].c,ct=1;   //      sort(v+1,v+m+1,cmp);     memset(f,64,sizeof f);    f[0]=0;    //表示第i列的城市需要的最少蓄水厂,如果在第j的范围内,    //则f[i]=min(f[v[j].l-1]+1,f[i]) 前一个j控制范围内最少蓄水厂+1     for (int i=1; i<=m; i++)        for (int j=1; j<=m; j++)            if (v[j].l<=i && v[j].r>=i) f[i]=min(f[i],f[v[j].l-1]+1);    printf("1\n%d",f[m]);    }}
原创粉丝点击