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\n",f[1][k]); 55 } 56 } 57 int main(){ 58 using namespace OI; 59 init(); 60 work(); 61 return 0; 62 }
[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\n",ans[i]); 74 } 75 void slove(){ 76 init(); 77 work(); 78 } 79 } 80 81 int main(){ 82 using namespace OI; 83 slove(); 84 }