弱鸡儿长乐爆零旅Day6
1 #include<iostream> 2 #include<cstdio> 3 #include<queue> 4 #include<cstring> 5 #define ll long long 6 using namespace std; 7 const ll INF=0x7f7f7f7f7f7f7f7f; 8 const int M =200010,N=50010; 9 int head1[N],head2[N],tot1,tot2,n; 10 ll d1[N],d2[N],d3[N],d4[N]; 11 bool v[N]; 12 struct Edge{ 13 ll val; 14 int to,nxt; 15 }e1[M],e2[M]; 16 void add1(int x,int y,ll z){ 17 e1[++tot1].to=y; 18 e1[tot1].val=z; 19 e1[tot1].next=head1[x]; 20 head1[x]=tot1; 21 //反向加边 22 e2[++tot2].to=x; 23 e2[tot2].val=z; 24 e2[tot2].next=head2[y]; 25 head2[y]=tot2; 26 } 27 void ADD(int x,int y) { 28 e2[++tot2].to=y; 29 e2[tot2].next=head2[x]; 30 head2[x]=tot; 31 } 32 void dijkstra(int t,ll d[],int head[],Edge e[]){ 33 for(int i=1;i<=n;i++) 34 d[i]=INF; 35 memset(v,0,sizeof(v)); 36 priority_queue< pair<ll,int> > q; 37 d[t]=0; 38 q.push(make_pair(0,t)); 39 while(q.size()){ 40 int now=q.top().second; 41 q.pop(); 42 if(v[now])continue; 43 v[now]=1; 44 for(int i=head[now];i;i =e[i].next) { 45 int next=e[i].to; 46 ll val=e[i].val; 47 if(d[next]>d[now]+val) { 48 d[next]=d[now]+val; 49 q.push(make_pair(-d[next], next)); 50 } 51 } 52 } 53 } 54 int in[N],f[N],ans;//in统计入度 55 void topusort(){//拓扑排序 56 queue<int> q; 57 for(int i=1;i<=n;i++) 58 if(!in[i]) q.push(i); 59 while(q.size()){ 60 int now=q.front(); 61 q.pop(); 62 for(int i=head2[now];i;i=e2[i].next){ 63 int next=e2[i].to; 64 f[next]=max(f[next],f[now]+1); 65 ans=max(ans,f[next]);//更新答案 66 in[next]--; 67 if(!in[next]) 68 q.push(next); 69 } 70 } 71 } 72 int main(){ 73 //拓扑序:在图中从顶点A到顶点B有一条有向路径,则顶点A一定排在顶点B之前。 74 //满足这样的条件的顶点序列称为一个拓扑序。 75 //简单来说,就是A顶点的输出一定是发生在B顶点之前。 76 //有了拓扑序 我们就可以由浅到深遍历一个有向无环图 77 //freopen("game.in","r",stdin); 78 //freopen("game.out","w",stdout); 79 int m; 80 scanf("%d%d", &n, &m); 81 for(int i=1;i<=m;i++){ 82 int a,b; 83 ll val; 84 scanf("%d%d%lld",&a,&b,&val); 85 add(a, b, val); 86 } 87 int a,b,c,d; 88 scanf("%d%d%d%d",&a,&b,&c,&d); 89 dijkstra(a,d1,head1,e1),dijkstra(b,d2,head2,e2); 90 dijkstra(c,d3,head1,e1),dijkstra(d,d4,head2,e2); 91 if(d1[b]==INF||d3[d]==INF) { 92 printf("-1"); 93 return 0; 94 }//有一个点走不到 95 int k=0; 96 for(int i=1;i<=n;i++) 97 if(d1[i]+d2[i]==d1[b]&&d3[i]+d4[i]==d3[d]) 98 {k=1;break;} //特殊情况 边上的点就重合 99 memset(e2,0,sizeof(e2)); 100 memset(head2,0,sizeof(head2)); 101 cnt2=0; 102 for(int i=1;i<=n;i++) { 103 for(int j=head1[i];j;j=e1[j].next) { 104 int next=e1[j].to; 105 if(d1[i]+d2[next]+e1[j].val==d1[b] && d3[i]+d4[next]+e1[j].val==d3[d]){ 106 in[next]++; 107 ADD(i,next); 108 } 109 } 110 } 111 topusort(); 112 printf("%d",ans+k); 113 return 0; 114 }
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 #include<algorithm> 6 using namespace std; 7 string s; 8 int ans=-1,n,K,f[510][150][150]; 9 int main() 10 { 11 freopen("welcome.in","r",stdin); 12 freopen("welcome.out","w",stdout); 13 scanf("%d%d",&n,&K); 14 cin>>s; 15 memset(f,0xcf,sizeof(f)); 16 f[0][0][0]=f[1][0][0]=0; 17 if(s[0]=='j') 18 f[1][1][0]=0; 19 else f[1][0][1]=0; 20 for(int k=2;k<=n;k++){ 21 for(int i=0;i<=K;i++){ 22 for(int j=0;j<=K;j++){ 23 f[k][i][j]=f[k-1][i][j]; 24 if(s[k-2]=='j' && s[k-1]=='z'){ 25 f[k][i][j]=max(f[k][i][j],f[k-2][i][j]+1); 26 } 27 if(j){ 28 if(s[k-2]=='z'&&s[k-1]=='z') 29 f[k][i][j]=max(f[k][i][j],f[k-2][i][j-1]+1); 30 } 31 if(i){ 32 if(s[k-2]=='j'&&s[k-1]=='j') 33 f[k][i][j]=max(f[k][i][j],f[k-2][i-1][j]+1); 34 } 35 if(i&&j){ 36 if(s[k-2]=='z' && s[k-1]=='j') 37 f[k][i][j]=max(f[k][i][j],f[k-2][i-1][j-1]+1); 38 } 39 if(i==j) 40 ans=max(ans,f[n][i][i]); 41 } 42 } 43 } 44 printf("%d",ans); 45 return 0; 46 }
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 int a[1000010]; 7 inline int read(){ 8 int res=0;char ch=getchar(); 9 while(ch<'0'||ch>'9'){ch=getchar();} 10 while(ch>='0'&&ch<='9'){res=res*10+ch-'0';ch=getchar();} 11 return res; 12 } 13 bool cmp(const int x,const int y){ 14 return x>y; 15 } 16 int ans,cnt0; 17 int main() 18 { 19 //倒推 大于0减1 有成对的0就合并 20 //如果在每一次都让大于零的元素减一 最坏的情况下时间复杂度为n^2 会超时(50分做法) 21 //我们先将数列中的元素从大到小排序,l和r表示为数列中为0的左右端点 22 //那么每次要合并的0的长度就为(l-r)/2(下取整) 23 //然后我们考虑大于零的情况 对于数列中的元素a[i] 变为0需要a[i]的时间 24 //由于已经排序 且数列的指针l是从右向左操作的 因此不会操作时存在前面的数在小于零的状况 25 freopen("multiset.in","r",stdin); 26 freopen("multiset.out","w",stdout); 27 int n=read(); 28 int max1=-1; 29 for(int i=1;i<=n;i++){ 30 a[i]=read(); 31 } 32 sort(a+1,a+1+n,cmp); 33 int l=n,r=n; 34 while(r>1){//r==1时数列中只剩下一个元素0; 35 while(a[l]==ans){ 36 l--; 37 } 38 ans++; 39 r-=(r-l)>>1; 40 } 41 printf("%d",ans); 42 return 0; 43 }