弱鸡儿长乐爆零旅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 }
T4
 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 }
T3
 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 } 
T2

 

posted @ 2019-07-27 22:28  Markill  阅读(170)  评论(0编辑  收藏  举报