zoukankan      html  css  js  c++  java
  • FOJ 11月月赛题解

    抽空在vjudge上做了这套题。剩下FZU 2208数论题不会。

    FZU 2205

    这是个想法题,每次可以在上一次基础上加上边数/2的新边。

     1 #include <iostream>
     2 #include <vector>
     3 #include <algorithm>
     4 #include <string>
     5 #include <string.h>
     6 #include <stdio.h>
     7 #include <queue>
     8 #include <stack>
     9 #include <map>
    10 #include <set>
    11 #include <cmath>
    12 #include <ctime>
    13 #include <cassert>
    14 #include <sstream>
    15 using namespace std;
    16 
    17 const int N=2001;
    18 
    19 int f[N];
    20 int main () {
    21     f[1]=0;
    22     for (int i=2;i<=1000;i++) {
    23         f[i]=f[i-1]+i/2;
    24     }
    25     int T;
    26     cin>>T;
    27     while (T--) {
    28         int n;
    29         cin>>n;
    30         cout<<f[n]<<endl;
    31     }
    32     return 0;
    33 }
    View Code

    FZU 2206

    乍看不知道什么东西,直接在机器上跑几个数字可以试出来结论。

     1 #include <iostream>
     2 #include <vector>
     3 #include <algorithm>
     4 #include <string>
     5 #include <string.h>
     6 #include <stdio.h>
     7 #include <queue>
     8 #include <stack>
     9 #include <map>
    10 #include <set>
    11 #include <cmath>
    12 #include <ctime>
    13 #include <cassert>
    14 #include <sstream>
    15 using namespace std;
    16 
    17 const int N=501;
    18 const int INF=0x3f3f3f3f;
    19 
    20 
    21 int main () {
    22     //freopen("out.txt","r",stdin);
    23     int T;
    24     scanf("%d",&T);
    25     for (int cas=1;cas<=T;cas++) {
    26         long long n;
    27         scanf("%I64d",&n);
    28         if (n<20150001LL) cout<<n+2014<<endl;
    29         else cout<<20152014<<endl;
    30     }
    31     return 0;
    32 }
    View Code

    FZU 2207

    会用倍增算LCA的话,这题也肯定会做。

      1 #include <iostream>
      2 #include <vector>
      3 #include <algorithm>
      4 #include <string>
      5 #include <string.h>
      6 #include <stdio.h>
      7 #include <queue>
      8 #include <stack>
      9 #include <map>
     10 #include <set>
     11 #include <cmath>
     12 #include <ctime>
     13 #include <cassert>
     14 #include <sstream>
     15 using namespace std;
     16 
     17 const int N=2001;
     18 
     19 vector<int>e[N];
     20 int fa[N][13];
     21 int dep[N];
     22 void dfs(int u,int f,int d) {
     23     dep[u]=d;
     24     for (int i=0;i<e[u].size();i++) {
     25         int v=e[u][i];
     26         if (v==f) continue;
     27         dfs(v,u,d+1);
     28         fa[v][0]=u;
     29     }
     30 }
     31 
     32 void calc(int n) {
     33     for (int j=1;j<=12;j++) {
     34         for (int i=1;i<=n;i++) {
     35             fa[i][j]=fa[fa[i][j-1]][j-1];
     36         }
     37     }
     38 }
     39 
     40 int kthA(int u,int k) {
     41     for (int i=12;i>=0;i--) {
     42         if (k>=(1<<i)){
     43             k-=(1<<i);
     44             u=fa[u][i];
     45         }
     46     }
     47     return u;
     48 }
     49 
     50 int lca(int u,int v) {
     51     if (dep[u]<dep[v]) swap(u,v);
     52     int d=dep[u]-dep[v];
     53     u=kthA(u,d);
     54     if (u==v) return u;
     55     for (int i=12;i>=0;i--) {
     56         if (fa[u][i]==fa[v][i])
     57             continue;
     58         u=fa[u][i];
     59         v=fa[v][i];
     60     }
     61     return fa[u][0];
     62 }
     63 int main () {
     64     int T;
     65     scanf("%d",&T);
     66     while (T--) {
     67         int n,m;
     68         scanf("%d %d",&n,&m);
     69         for (int i=0;i<=n;i++)
     70             e[i].clear();
     71         for (int i=1;i<n;i++) {
     72             int u,v;
     73             scanf("%d %d",&u,&v);
     74             e[u].push_back(v);
     75             e[v].push_back(u);
     76         }
     77         dfs(1,-1,1);
     78         calc(n);
     79         static int cas=1;
     80         printf("Case #%d:
    ",cas++);
     81         while (m--) {
     82             int u,v,k;
     83             scanf("%d %d %d",&u,&v,&k);
     84             int ans=lca(u,v);
     85             if (k==1) {
     86                 printf("%d
    ",u);
     87                 continue;
     88             }
     89             else if (k==dep[u]-dep[ans]+dep[v]-dep[ans]+1) {
     90                 printf("%d
    ",v);
     91                 continue;
     92             }
     93             if (dep[u]-dep[ans]+1>=k) {
     94                 int ret=kthA(u,k-1);
     95                 printf("%d
    ",ret);
     96             }
     97             else {
     98                 int to=dep[u]-dep[ans]+dep[v]-dep[ans]+1-k;
     99                 int ret=kthA(v,to);
    100                 printf("%d
    ",ret);
    101             }
    102         }
    103     }
    104     return 0;
    105 }
    View Code

    FZU 2208

    数论题,不会

    FZU 2209

    分层图。

      1 #include <iostream>
      2 #include <vector>
      3 #include <algorithm>
      4 #include <string>
      5 #include <string.h>
      6 #include <stdio.h>
      7 #include <queue>
      8 #include <stack>
      9 #include <map>
     10 #include <set>
     11 #include <cmath>
     12 #include <ctime>
     13 #include <cassert>
     14 #include <sstream>
     15 using namespace std;
     16 
     17 const int N=501;
     18 const int INF=0x3f3f3f3f;
     19 int get(int n,int u,int k) {
     20     return k*n+u;
     21 }
     22 struct Edge {
     23     int to,next,len;
     24     Edge() {}
     25     Edge(int _to,int _next,int _len):to(_to),next(_next),len(_len) {}
     26 } edge[250000];
     27 int idx=1,head[N];
     28 inline void addedge(int u,int v,int l) {
     29     edge[++idx]=Edge(v,head[u],l);
     30     head[u]=idx;
     31 }
     32 int dis[N][N],in[N];
     33 bool vis[N];
     34 bool spfa(int s,int n,int *dis) {
     35     fill(dis,dis+N,INF);
     36     memset(vis,false,sizeof(vis));
     37     memset(in,0,sizeof(in));
     38     dis[s]=0;
     39     vis[s]=true;
     40     queue<int> que;
     41     que.push(s);
     42     in[s]=1;
     43     while (!que.empty()) {
     44         int u=que.front();
     45         que.pop();
     46         vis[u]=false;
     47         for (int k=head[u];k;k=edge[k].next) {
     48             int v=edge[k].to;
     49             if (dis[v]>dis[u]+edge[k].len) {
     50                 dis[v]=dis[u]+edge[k].len;
     51                 if (!vis[v]) {
     52                     vis[v]=true;
     53                     in[v]++;
     54                     if (in[v]>n) return false;
     55                     que.push(v);
     56                 }
     57             }
     58         }
     59     }
     60     return true;
     61 }
     62 int main () {
     63     //freopen("out.txt","r",stdin);
     64     int T;
     65     scanf("%d",&T);
     66     for (int cas=1;cas<=T;cas++) {
     67         int n,m,k;
     68         scanf("%d %d %d",&n,&m,&k);
     69         idx=1;memset(head,0,sizeof head);
     70         for (int i=1;i<=m;i++) {
     71             int u,v;
     72             scanf("%d %d",&u,&v);
     73             int d;
     74             for (int i=0;i<24;i++) {
     75                 scanf("%d",&d);
     76                 int uu=get(n,u,i);
     77                 int vv=get(n,v,(i+d)%24);
     78                 addedge(uu,vv,d);
     79                 uu=get(n,v,i);
     80                 vv=get(n,u,(i+d)%24);
     81                 addedge(uu,vv,d);
     82             }
     83         }
     84         for (int i=0;i<24;i++) {
     85             spfa(get(n,1,i),n*24,dis[i]);
     86         }
     87         printf("Case #%d:",cas);
     88         while (k--) {
     89             int v,s;
     90             scanf("%d %d",&v,&s);
     91             //cout<<"from "<<get(n,1,s)<<endl;
     92             int ret=0x3f3f3f3f;
     93             for (int i=0;i<24;i++) {
     94                 int p=get(n,v,i);
     95                 ret=min(ret,dis[s][p]);
     96             }
     97             if (ret==0x3f3f3f3f) ret=-1;
     98             printf(" %d",ret);
     99         }
    100         puts("");
    101     }
    102     return 0;
    103 }
    View Code

    FZU 2210

    建立一个虚拟节点,连向所有粮仓,枚举所有禁止的城市,从虚拟节点dfs,更新答案。

     1 #include <iostream>
     2 #include <vector>
     3 #include <algorithm>
     4 #include <string>
     5 #include <string.h>
     6 #include <stdio.h>
     7 #include <queue>
     8 #include <stack>
     9 #include <map>
    10 #include <set>
    11 #include <cmath>
    12 #include <ctime>
    13 #include <cassert>
    14 #include <sstream>
    15 using namespace std;
    16 
    17 const int N=2001;
    18 
    19 vector<int>e[N];
    20 int in[N];
    21 bool vis[N];
    22 int fob;
    23 int cnt;
    24 void dfs(int u) {
    25     if (u==fob||vis[u]) return;
    26     vis[u]=true;cnt++;
    27     for (int i=0;i<e[u].size();i++) {
    28         int v=e[u][i];
    29         dfs(v);
    30     }
    31 }
    32 int main () {
    33     int n,m;
    34     while (scanf("%d %d",&n,&m)!=EOF) {
    35         for (int i=0;i<=n;i++){
    36             e[i].clear();
    37             in[i]=0;
    38         }
    39         for (int i=1;i<=m;i++) {
    40             int u,v;
    41             scanf("%d %d",&u,&v);
    42             e[u].push_back(v);
    43             in[v]++;
    44         }
    45         for (int i=1;i<=n;i++) {
    46             if (in[i]==0)
    47                 e[0].push_back(i);
    48         }
    49         int ret=n+1,val=0;
    50         for (int i=n;i>=1;i--) {
    51             fob=i;
    52             memset(vis,false,sizeof vis);
    53             cnt=0;
    54             dfs(0);
    55             cnt--;
    56             if (n-cnt>=val) {
    57                 val=n-cnt;
    58                 ret=i;
    59             }
    60         }
    61         cout<<ret<<endl;
    62     }
    63     return 0;
    64 }
    View Code

    FZU 2211

    费用流,把所有蘑菇拆成两个点,根据时间关系,互相连边。农田的限制在于源点出来的流的大小。

      1 #include <iostream>
      2 #include <vector>
      3 #include <algorithm>
      4 #include <string>
      5 #include <string.h>
      6 #include <stdio.h>
      7 #include <queue>
      8 #include <stack>
      9 #include <map>
     10 #include <set>
     11 #include <cmath>
     12 #include <ctime>
     13 #include <cassert>
     14 #include <sstream>
     15 using namespace std;
     16 
     17 const int N=5010;
     18 const int INF=0x3f3f3f3f;
     19 
     20 struct Edge{
     21     int to,next,f;
     22     long long c;
     23     Edge(){}
     24     Edge(int _to,int _nxt,int _f,long long _c):to(_to),next(_nxt),f(_f),c(_c){}
     25 }edge[N<<2];
     26 
     27 int head[N],idx;
     28 bool vis[N];
     29 long long dis[N];
     30 int pree[N],prev[N];
     31 void addedge(int u,int v,int flow,long long cost){
     32     edge[++idx]=Edge(v,head[u],flow,cost);
     33     head[u]=idx;
     34     edge[++idx]=Edge(u,head[v],0,-cost);
     35     head[v]=idx;
     36 }
     37 bool spfa(int s,int e){
     38     memset(vis,0,sizeof(vis));
     39     memset(pree,-1,sizeof(pree));
     40     memset(prev,-1,sizeof(prev));
     41     for (int i=0;i<N;i++) dis[i]=~0ULL>>3;
     42     dis[s]=0;
     43     vis[s]=true;
     44     queue<int>que;
     45     que.push(s);
     46     while (!que.empty()){
     47         int cur=que.front();
     48         que.pop();
     49         vis[cur]=false;
     50         for (int k=head[cur];k;k=edge[k].next){
     51             if (edge[k].f){
     52                 int n=edge[k].to;
     53                 if (dis[n]>dis[cur]+edge[k].c){
     54                     dis[n]=dis[cur]+edge[k].c;
     55                     prev[n]=cur;
     56                     pree[n]=k;
     57                     if (!vis[n]){
     58                         vis[n]=true;
     59                         que.push(n);
     60                     }
     61                 }
     62             }
     63         }
     64     }
     65     if (dis[e]>=INF) return 0;
     66     return 1;
     67 }
     68 long long minCostMaxFlow(int src,int sink){
     69     long long cur,min_val;
     70     long long ansf=0,ansc=0;
     71     while (spfa(src,sink)){
     72          cur=sink;
     73          min_val=INF;
     74          while (prev[cur]!=-1){
     75             if (min_val>edge[pree[cur]].f)
     76                 min_val=edge[pree[cur]].f;
     77             cur=prev[cur];
     78          }
     79          cur=sink;
     80          while (prev[cur]!=-1){
     81             edge[pree[cur]].f-=min_val;
     82             edge[pree[cur]^1].f+=min_val;
     83             cur=prev[cur];
     84          }
     85          ansc+=dis[sink]*min_val;
     86          ansf+=min_val;
     87     }
     88     return ansc;
     89 }
     90 
     91 int s[N],t[N],v[N];
     92 int main () {
     93     int T;
     94     scanf("%d",&T);
     95     for (int cas=1;cas<=T;cas++) {
     96         int n,m;
     97         scanf("%d %d",&n,&m);
     98         for (int i=1;i<=m;i++) {
     99             scanf("%d %d %d",s+i,t+i,v+i);
    100         }
    101         idx=1;memset(head,0,sizeof head);
    102         for (int i=1;i<=m;i++) {
    103             for (int j=1;j<=m;j++) {
    104                 if (t[i]<s[j]) {
    105                     addedge(i+m,j,INF,0);
    106                 }
    107             }
    108         }
    109         int s=m+m+1,t=m+m+1+1;
    110         for (int i=1;i<=m;i++) {
    111             addedge(0,i,INF,0);
    112             addedge(i,i+m,1,-v[i]);
    113             addedge(i+m,t,INF,0);
    114         }
    115         addedge(s,0,n,0);
    116         long long ret=-minCostMaxFlow(s,t);
    117         cout<<ret<<endl;
    118     }
    119     return 0;
    120 }
    View Code
  • 相关阅读:
    不上大学遗撼,上过大学后悔
    消息队列(MSMQ)实现多服务器应用程序之间消息实时交互
    抓取网页源代码
    用asp.net显示在线登陆人数及位置
    原版对XML文档的读写
    C#.NET实现经典排序算法
    深入剖析C#继承机制
    ASP.NET长文章分页
    人民币小写金额转化成大写金额
    GridView和DataFormatString
  • 原文地址:https://www.cnblogs.com/micrari/p/4993432.html
Copyright © 2011-2022 走看看