正睿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\n",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由于能力不够....就咕咕咕了....

猜你喜欢

转载自www.cnblogs.com/degage/p/9697207.html