P1604&P1601

[usaco2010]冲浪_slide

受到秘鲁的马丘比丘的新式水上乐园的启发,Farmer John决定也为奶牛们建一个水上乐园。当然,它最大的亮点就是新奇巨大的水上冲浪。
::点击图片在新窗口中打开::
  超级轨道包含 E (1 <= E <=150,000)条小轨道连接着V (V <= 50,000)个水池,编号为1..V。每个小轨道必须按照特定的方向运行,不能够反向运行。奶牛们从1号水池出发,经过若干条小轨道,最终到达V号水池。每个水池(除了V号和1号之外,都有至少一条小轨道进来和一条小轨道出去,并且,一头奶牛从任何一个水池到达V号水池。最后,由于这是一个冲浪,从任何一个水池出发都不可能回到这个水池) 
  
  每条小轨道从水池P_i到水池Q_i (1 <= P_i <= V; 1<= Q_i <= V; P_i != Q_i),轨道有一个开心值F_i (0 <= F_i <= 2,000,000,000),Bessie总的开心值就是经过的所有轨道的开心值之和。
Bessie自然希望越开心越好,并且,她有足够长的时间在轨道上玩。因此,她精心地挑选路线。但是,由于她是头奶牛,所以,会有至多K (1 <= K <= 10)次的情况,她无法控制,并且随机从某个水池选择了一条轨道(这种情况甚至会在1号水池发生)
  如果Bessie选择了在最坏情况下,最大化她的开心值,那么,她在这种情况下一次冲浪可以得到的最大开心值是多少?
  在样例中,考虑一个超级轨道,包含了3个水池(在图中用括号表示)和4条小轨道,K的值为1(开心值在括号外表示出来,用箭头标识)
::点击图片在新窗口中打开::
  她总是从1号水池出发,抵达3号水池。如果她总是可以自己选择,就是不会发生不能控制的情况她可以选择从1到2(这条轨道开心值为5),再从2到3(开心值为5),总的开心值为5+5=10。但是,如过她在1号水池失去控制,直接到了3,那么开心值为9,如果她在2号水池失去控制,她总的开心值为8。
  Bessie想要找到最大化开心值的方案,可以直接从1到3,这样,如果在1号水池失去控制,这样,她就不会在2号水池失去控制了,就能够得到10的开心值。因此,她的开心值至少为9。

这题最折腾人的是题目描述,语文不佳者勿入;

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<cstdlib>
 5 #include<algorithm>
 6 #include<iomanip>
 7 #include<map>
 8 #include<set>
 9 #include<vector>
10 #include<ctime>
11 #include<cmath>
12 #define LL long long 
13 using namespace std;
14 #define LL long long 
15 #define up(i,j,n) for(int i=(j);(i)<=(n);(i)++)
16 #define max(x,y) ((x)<(y)?(y):(x))
17 #define min(x,y) ((x)<(y)?(x):(y))
18 namespace OI{
19 const int maxn=50500;
20 struct node{
21     int y,next,v;
22 }e[150100],E[150100];
23 int linkk[maxn],linker[maxn],q[maxn],len=0,Len=0;
24 int n,m,k,chu[maxn];
25 LL f[maxn][15];
26 void insert(int x,int y,int v){
27     e[++len].next=linkk[x];
28     linkk[x]=len;
29     e[len].v=v;
30     e[len].y=y;
31     E[++Len].y=x;
32     E[Len].next=linker[y];
33     linker[y]=Len;
34 }
35 void init(){
36     scanf("%d%d%d",&n,&m,&k);
37     int x,y,v;
38     up(i,1,m){
39         scanf("%d%d%d",&x,&y,&v);
40         insert(x,y,v);chu[x]++;
41     }
42 }
43 void work(){
44     int head=0,tail=0,x=0;
45     q[++tail]=n;
46     while(++head<=tail){
47         x=q[head];
48         for(int i=linkk[x];i;i=e[i].next)
49             for(int j=0;j<=k;j++)f[x][j]=max(f[x][j],f[e[i].y][j]+e[i].v);
50         for(int i=linkk[x];i;i=e[i].next)
51             for(int j=1;j<=k;j++)f[x][j]=min(f[x][j],f[e[i].y][j-1]+e[i].v);
52         for(int i=linker[x];i;i=E[i].next)if(--chu[E[i].y]==0)q[++tail]=E[i].y;
53     }
54     printf("%I64d
",f[1][k]);
55 }
56 }
57 int main(){
58     using namespace OI;
59     init();
60     work();
61     return 0;
62 }
View Code

[usaco2008dec]万圣节采糖

每年万圣节,Fj的奶牛都要打扮一番,出门在农场里N(1<=N<=100000)个牛棚里转悠,来采集糖果,她们每走到一个未曾经过的牛棚,就会采集这个棚里1棵糖果。
Fj为了让奶牛少采集糖果,他给每个牛棚设置了一个”后继牛棚”,牛棚i的后继牛棚是Xi,他告诉奶牛们,她们到了一个牛棚后,只要再往后继牛棚走去,就可以搜集到更多的糖果。
第i只奶牛从牛棚i开始她的旅程。请你计算,每一只奶牛可以采集到多少 糖果。

各种方法都可以做,我直接上最暴力的方法了;

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<cstdlib>
 5 #include<algorithm>
 6 #include<iomanip>
 7 #include<map>
 8 #include<set>
 9 #include<vector>
10 #include<ctime>
11 #include<cmath>
12 #define LL long long 
13 using namespace std;
14 #define LL long long 
15 #define up(i,j,n) for(int i=(j);(i)<=(n);(i)++)
16 #define max(x,y) ((x)<(y)?(y):(x))
17 #define min(x,y) ((x)<(y)?(x):(y))
18 #define FILE "1"
19 namespace OI{
20     const int maxn=101000;
21     int a[maxn],x,y,cnt=0,ru[maxn],ans[maxn],f[maxn];
22     int n;
23     int q[maxn],head=0,tail=0;
24     vector<int> G[maxn];
25     bool vis[maxn];
26     void init(){
27         freopen(FILE".in","r",stdin);
28         freopen(FILE".out","w",stdout);
29         scanf("%d",&n);
30         for(int i=1;i<=n;i++){
31             scanf("%d",&a[i]);
32             ru[a[i]]++;G[a[i]].push_back(i);
33         }
34     }
35     void dfs3(int fa,int x){
36         ans[x]=ans[fa]+1;
37         for(int i=0;i<G[x].size();i++){
38             if(!ans[G[x][i]])dfs3(x,G[x][i]);
39         }
40     }
41     void bfs(int fa,int s){
42         tail=0,head=0;
43         q[++tail]=s;f[s]=fa;
44         while(++head<=tail){
45             x=q[head];ans[x]=ans[f[x]]+1;
46             for(int j=0;j<G[x].size();j++){
47                 if(!ans[G[x][j]]){
48                     f[G[x][j]]=x;
49                     q[++tail]=G[x][j];
50                 }
51             }
52         }
53     }
54     void work(){
55         up(i,1,n)if(!ru[i])q[++tail]=i;
56         while(++head<=tail){
57             x=q[head];vis[x]=1;
58             if(--ru[a[x]]==0)q[++tail]=a[x];
59         }
60         up(i,1,n)if(!vis[i]){
61             int u=i;cnt=0;
62             do{cnt++;vis[u]=1;u=a[u];
63             }while(u!=i);
64             do{ans[u]=cnt;u=a[u];
65             }while(u!=i);
66             do{
67                 for(int j=0;j<G[u].size();j++){
68                     if(!ans[G[u][j]])bfs(u,G[u][j]);
69                 }
70                 u=a[u];
71             }while(i!=u);
72         }
73         up(i,1,n)printf("%d
",ans[i]);
74     }
75     void slove(){
76         init();
77         work();
78     }
79 }
80 
81 int main(){
82     using namespace OI;
83     slove();
84 }
View Code
原文地址:https://www.cnblogs.com/chadinblog/p/5935896.html