zoukankan      html  css  js  c++  java
  • 正睿OI普转提day18

    前言:这个.....难度有点超a....

    T1:嘤

    首先要观察出结论,2*2的小矩阵满足记为1,不满足记为0,那么求最大的1矩阵,还是很好证明的,推一下.....主要是这个找最大1矩阵得优化为O(n*m)的

    主要是加个单调栈维护....

    上代码:

     1 #include<bits/stdc++.h>
     2 #define maxn 1005
     3 using namespace std;
     4 int n,m,a[maxn][maxn];
     5 int vis[maxn][maxn];
     6 int st[maxn],top=0; 
     7 void init(){
     8     scanf("%d%d",&n,&m);
     9     for(int i=1;i<=n;i++)
    10     for(int j=1;j<=m;j++) scanf("%d",&a[i][j]);
    11     
    12     for(int i=1;i<=n;i++)
    13     for(int j=1;j<=m;j++) vis[i][j]=1;
    14     
    15     for(int i=2;i<=n;i++)
    16     for(int j=2;j<=m;j++){
    17         if(a[i-1][j-1]+a[i][j]<=a[i][j-1]+a[i-1][j]) vis[i][j]=vis[i][j-1]+1;
    18     }
    19     for(int i=1;i<=n;i++){
    20         for(int j=1;j<=m;j++){
    21           if(vis[i][j]==1) vis[i][j]=0;//大格格到小格格 
    22         } 
    23     }
    24     
    25     st[0]=1;
    26     int maxx=0;
    27     for(int j=2;j<=m;j++){//要加个单调栈优化
    28         top=0;
    29         for(int i=2;i<=n;i++){
    30             while(top&&vis[i][j]<=vis[st[top]][j]){//小于等于保证是0就续接 
    31                 maxx=max(maxx,vis[st[top]][j]*(i-st[top-1]));//让前一个被计算完
    32                 top--; 
    33             }
    34             st[++top]=i;//加进去重新开始记 
    35         }
    36         while(top){//将前面的小的计算完,可以贯穿全部的23333
    37             maxx=max(maxx,vis[st[top]][j]*(n+1-st[top-1]));//贯穿全部,细节!!!
    38             top--; 
    39         } 
    40     }
    41     
    42     printf("%d",maxx);
    43 }
    44 int main(){
    45     init();
    46     
    47     return 0;
    48 }

    T2:

    考基本算法的一个,首先要跑出最短路图,方法:

    正反跑一遍最短路,然后对于每条边,设其两节点为u,v,若dist1[u]+distn[v]+这条边边权==dist1[n],则将这条边加入到最短路图中。

    然后对于最短路图求出桥边,即可。这样删去桥边最短路就只有增大。

    上代码:

     1 #include<bits/stdc++.h>
     2 #define maxn 100005
     3 using namespace std;
     4 int n,m,x,y,z;
     5 struct eage{
     6     int from,to,next,len;
     7 }e[maxn<<1];
     8 int np=0,first[maxn];
     9 int dist1[maxn],distn[maxn];
    10 bool vis[maxn];
    11 struct node{
    12     int v,id;
    13     friend bool operator <(node a,node b){
    14         return a.v>b.v;
    15     }
    16 };
    17 struct eagee{
    18     int to,next,id;
    19 }ee[maxn<<1];
    20 int npp=0,fir[maxn];
    21 void add1(int u,int v,int id){
    22     ee[++npp]=(eagee){v,fir[u],id};
    23     fir[u]=npp;
    24 }
    25 void bfs(int s,int *dist){
    26     priority_queue<node>q;
    27     for(int i=1;i<=n;i++) dist[i]=0x3f3f3f3f;
    28     memset(vis,0,sizeof(vis));
    29     dist[s]=0;
    30     q.push((node){dist[s],s});
    31     while(!q.empty()){
    32         node t=q.top();q.pop();
    33         int i=t.id;
    34         if(vis[i]) continue;
    35         vis[i]=1;
    36         for(int p=first[i];p;p=e[p].next){
    37             int j=e[p].to,c=e[p].len;
    38             if(dist[j]>dist[i]+c){
    39                 dist[j]=dist[i]+c;
    40                 q.push((node){dist[j],j});
    41             }
    42         }
    43     }
    44 }
    45 void add(int from,int u,int v,int len){
    46     e[++np]=(eage){from,v,first[u],len};
    47     first[u]=np;
    48 }
    49 int st[maxn],top=0;
    50 int dfn[maxn],clock_=0,low[maxn];
    51 bool viss[maxn];
    52 void tarjan(int i,int fb){
    53     viss[i]=1;
    54     dfn[i]=low[i]=++clock_;
    55     for(int p=fir[i];p;p=ee[p].next){
    56         int j=ee[p].to,id=ee[p].id;
    57         if(id==fb) continue;
    58         if(viss[j]){
    59             if(dfn[j]<dfn[i]) low[i]=min(low[i],dfn[j]);
    60             continue;
    61         }
    62         tarjan(j,id);
    63         low[i]=min(low[i],low[j]);
    64     }
    65     if(low[i]==dfn[i]&&fb!=0){
    66         st[++top]=fb;
    67     }
    68 }
    69 void init(){
    70     scanf("%d%d",&n,&m);
    71     for(int i=1;i<=m;i++){
    72         scanf("%d%d%d",&x,&y,&z);
    73         add(x,x,y,z);
    74         add(y,y,x,z);
    75     }
    76     bfs(1,dist1);
    77     bfs(n,distn);
    78     
    79     for(int i=1;i<=np;i++){
    80         int u=e[i].from,v=e[i].to,len=e[i].len;
    81         int id=((i&1)?i/2+1:i/2);
    82         if(dist1[u]+len+distn[v]==dist1[n])
    83         add1(u,v,id),add1(v,u,id);
    84     }
    85     
    86     tarjan(1,0);
    87     sort(st+1,st+top+1);
    88     printf("%d
    ",top);
    89     for(int i=1;i<=top;i++){
    90         printf("%d ",st[i]);
    91     }
    92 }
    93 int main(){
    94     init();
    95     
    96     return 0;
    97 }

    T3,T4由于能力不够....就咕咕咕了....

  • 相关阅读:
    vc++6.0如何调试
    Visual C++单文档混合分割视图
    使用VC6.0实现窗口的任意分割张中庆
    用MFC创建通用窗体分割框架
    vc++6.0编译环境介绍(1、2)
    浅谈SDI单文档多视切换方法
    单文档多视图Formview切换源代码(此网还有许多其它多视图切换的源代码)
    VC单文档实现多视图的方法
    Visual C++(VC++6.0)编译器常用选项设置
    PowerTip of the DayRemoving Empty Things
  • 原文地址:https://www.cnblogs.com/degage/p/9697207.html
Copyright © 2011-2022 走看看