1. 程式人生 > >9.8——模擬賽

9.8——模擬賽

and 天下 ins ble counter gist there .html increase

T1 洛谷 P2966 [USACO09DEC]牛收費路徑Cow Toll Paths

題目描述

Like everyone else, FJ is always thinking up ways to increase his revenue. To this end, he has set up a series of tolls that the cows will pay when they traverse the cowpaths throughout the farm.

The cows move from any of the N (1 <= N <= 250) pastures conveniently numbered 1..N to any other pasture over a set of M (1 <= M <= 10,000) bidirectional cowpaths that connect pairs of different pastures A_j and B_j (1 <= A_j <= N; 1 <= B_j <= N). FJ has assigned a toll L_j (1 <= L_j <= 100,000) to the path connecting pastures A_j and B_j.

While there may be multiple cowpaths connecting the same pair of pastures, a cowpath will never connect a pasture to itself. Best of all, a cow can always move from any one pasture to any other pasture by following some sequence of cowpaths.

In an act that can only be described as greedy, FJ has also assigned a toll C_i (1 <= C_i <= 100,000) to every pasture. The cost of moving from one pasture to some different pasture is the sum of the tolls for each of the cowpaths that were traversed plus a *single additional toll* that is the maximum of all the pasture tolls encountered along the way, including the initial and destination pastures.

The patient cows wish to investigate their options. They want you to write a program that accepts K (1 <= K <= 10,000) queries and outputs the minimum cost of trip specified by each query. Query i is a pair of numbers s_i and t_i (1 <= s_i <= N; 1 <= t_i <= N; s_i != t_i) specifying a starting and ending pasture.

Consider this example diagram with five pastures:

The ‘edge toll‘ for the path from pasture 1 to pasture 2 is 3. Pasture 2‘s ‘node toll‘ is 5.

To travel from pasture 1 to pasture 4, traverse pastures 1 to 3 to 5 to 4. This incurs an edge toll of 2+1+1=4 and a node toll of 4 (since pasture 5‘s toll is greatest), for a total cost of 4+4=8.

The best way to travel from pasture 2 to pasture 3 is to traverse pastures 2 to 5 to 3. This incurs an edge toll of 3+1=4 and a node toll of 5, for a total cost of 4+5=9.

跟所有人一樣,農夫約翰以著寧教我負天下牛,休叫天下牛負我的偉大精神,日日夜夜苦思生 財之道。為了發財,他設置了一系列的規章制度,使得任何一只奶牛在農場中的道路行走,都 要向農夫約翰上交過路費。 農場中由N(1 <= N <= 250)片草地(標號為1到N),並且有M(1 <= M <= 10000)條 雙向道路連接草地A_j和B_j(1 <= A_j <= N; 1 <= B_j <= N)。

奶牛們從任意一片草 地出發可以抵達任意一片的草地。FJ已經在連接A_j和B_j的雙向道路上設置一個過路費L_j (1 <= L_j <= 100,000)。 可能有多條道路連接相同的兩片草地,但是不存在一條道路連接一片草地和這片草地本身。最 值得慶幸的是,奶牛從任意一篇草地出發,經過一系列的路徑,總是可以抵達其它的任意一片 草地。 除了貪得無厭,叫獸都不知道該說什麽好。

FJ竟然在每片草地上面也設置了一個過路費C_i (1 <= C_i <= 100000)。從一片草地到另外一片草地的費用,是經過的所有道路的過路 費之和,加上經過的所有的草地(包括起點和終點)的過路費的最大值。 任勞任怨的牛們希望去調查一下她們應該選擇那一條路徑。

她們要你寫一個程序,接受K(1 <= K <= 10,000)個問題並且輸出每個詢問對應的最小花費。第i個問題包含兩個數字s_i 和t_i(1 <= s_i <= N; 1 <= t_i <= N; s_i != t_i),表示起點和終點的草地。

輸入輸出格式

輸入格式:

  • Line 1: Three space separated integers: N, M, and K

  • Lines 2..N+1: Line i+1 contains a single integer: C_i

  • Lines N+2..N+M+1: Line j+N+1 contains three space separated

integers: A_j, B_j, and L_j

  • Lines N+M+2..N+M+K+1: Line i+N+M+1 specifies query i using two space-separated integers: s_i and t_i

輸出格式:

  • Lines 1..K: Line i contains a single integer which is the lowest cost of any route from s_i to t_i

輸入輸出樣例

輸入樣例#1:
5 7 2 
2 
5 
3 
3 
4 
1 2 3 
1 3 2 
2 5 3 
5 3 1 
5 4 1 
2 4 3 
3 4 4 
1 4 
2 3 
輸出樣例#1:
8 
9 


n的範圍支持n^3的Floyd,然後、、
技術分享
 1 #include <cstdio>
 2 
 3 const int INF(0x3f3f3f3f);
 4 const int N(250+26);
 5 int n,m,p,point[N];
 6 int ans[N][N],maxp[N][N],dis[N][N];
 7 
 8 inline void read(int &x)
 9 {
10     x=0; register char ch=getchar();
11     for(; ch>9||ch<0; ) ch=getchar();
12     for(; ch>=0&&ch<=9; ch=getchar()) x=x*10+ch-0;
13 }
14 
15 #define min(a,b) (a<b?a:b)
16 #define max(a,b) (a>b?a:b)
17 
18 int AC()
19 {
20     freopen("fee.in","r",stdin);
21     freopen("fee.out","w",stdout);
22     
23     read(n),read(m),read(p);
24     for(int i=1; i<=n; ++i)
25       for(int j=1; j<=n; ++j)
26         dis[i][j]=INF*(i!=j);
27     for(int i=1; i<=n ;++i)
28         read(point[i]);
29     for(int u,v,w; m--; )
30     {
31         read(u),read(v),read(w);
32         dis[u][v]=min(dis[u][v],w);
33         dis[v][u]=dis[u][v];
34     }
35     for(int k=1; k<=n; ++k)
36       for(int i=1; i<=n; ++i)
37           for(int j=1; j<=n; ++j)
38             if(dis[i][j]>dis[i][k]+dis[k][j])
39             {
40               dis[i][j]=dis[i][k]+dis[k][j];
41             maxp[i][j]=max(point[i],point[j]);
42               maxp[i][j]=max(maxp[i][k],maxp[k][j]);
43               maxp[i][j]=max(maxp[i][j],point[k]);
44           }
45         else if(dis[i][j]<dis[i][k]+dis[k][j])
46             maxp[i][j]=max(point[i],point[j]);
47     for(int s,t; p--; )
48     {
49         read(s),read(t);
50         if(s==t) printf("%d\n",point[s]);
51         else if(dis[s][t]+maxp[s][t]>=INF) puts("-1");
52         else printf("%d\n",dis[s][t]+maxp[s][t]);
53     }
54     return 0;
55 }
56 
57 int Hope=AC();
58 int main(){;}
20分。

先給點權排序,使的在最短路更新時,i-->j 這條路徑上,依次枚舉點權從小到大的中轉點k

每次由最短路更新出ans,保證ans的正確、

技術分享
 1 #include <algorithm>
 2 #include <cstdio>
 3 
 4 const int INF(0x3f3f3f3f);
 5 const int N(250+26);
 6 int n,m,p,point[N],s[N];
 7 int ans[N][N],dis[N][N];
 8 
 9 inline void read(int &x)
10 {
11     x=0; register char ch=getchar();
12     for(; ch>9||ch<0; ) ch=getchar();
13     for(; ch>=0&&ch<=9; ch=getchar()) x=x*10+ch-0;
14 }
15 
16 #define min(a,b) (a<b?a:b)
17 #define max(a,b) (a>b?a:b)
18 
19 bool cmp(int a,int b)
20 {
21     return point[a]<point[b];
22 }
23 
24 int AC()
25 {
26 //    freopen("fee.in","r",stdin);
27 //    freopen("fee.out","w",stdout);
28     
29     read(n),read(m),read(p);
30     for(int i=1; i<=n; ++i)
31       for(int j=1; j<=n; ++j)
32         ans[i][j]=dis[i][j]=INF*(i!=j);
33     for(int i=1; i<=n ;++i)
34         read(point[i]),s[i]=i,ans[i][i]=point[i];
35     std::sort(s+1,s+n+1,cmp);
36     for(int u,v,w; m--; )
37     {
38         read(u),read(v),read(w);
39         dis[u][v]=min(dis[u][v],w);
40         dis[v][u]=dis[u][v];
41     }
42     for(int k=1; k<=n; ++k)
43       for(int i=1; i<=n; ++i)
44           for(int j=1; j<=n; ++j)
45           {
46               dis[s[i]][s[j]]=min(dis[s[i]][s[j]],dis[s[i]][s[k]]+dis[s[k]][s[j]]);
47               ans[s[i]][s[j]]=min(ans[s[i]][s[j]],dis[s[i]][s[j]]+
48                               max(point[s[k]],max(point[s[i]],point[s[j]])));
49         }
50     for(int s,t; p--; )
51     {
52         read(s),read(t);
53         if(ans[s][t]>=INF) puts("-1");
54         else printf("%d\n",ans[s][t]);
55     }
56     return 0;
57 }
58 
59 int Hope=AC();
60 int main(){;}
AC

T2 走樓梯升級版

Description

在你成功地解決了上一道走樓梯後,xxy 不禁有些氣惱,於是她又在樓梯上跳來跳去,想要你求出她跳的方案數。..

xxy 站在一個 tot 階樓梯下面,他每次可以往上跳1—n步,往下跳1——m步(由於地心引力跳得比較遠),而且在往下跳的時候只能踩在往上跳時踩過的格子。

現在 xxy 在樓梯上亂跳,想問她跳到樓梯頂上最後又跳回樓梯下面的方案數 mod 233333333。

註意:xxy 只能一直向上跳,跳到樓梯最上面,然後再往下跳,跳回樓梯最底下。

Input

一行3個整數 totnm

Output

方案數 % 233333333

Example

Input

2

5 2 4

5 2 3

Output

52

42

Hint

10%的數據,1<=tot,n<=5,m=1

另外10%的數據, 1<=tot,n,m<=5

另外20%的數據, 1<=tot<=10000,1<=n,m<=5

另外20%的數據, 1<=tot<=10000,1<=n,m<=10

另外20%的數據, 1<=tot<=400000,1<=n,m<=5

對於100%的數據,1<=tot<=400000,1<=n,m<=10

考試想出正解做法,結果、、、沒考慮long long ,還在預處理的時候打錯變量了。。w(?Д?)w zz啊。

技術分享
  1 #include <cstring>
  2 #include <cstdio>
  3 
  4 const int mod(233333333);
  5 const int N(400000+626);
  6 int n,m,tot,a[N],f[N];
  7 
  8 inline void read(int &x)
  9 {
 10     x=0; register char ch=getchar();
 11     for(;ch>9||ch<0;) ch=getchar();
 12     for(;ch>=0&&ch<=9;ch=getchar()) x=x*10+ch-0;
 13 }
 14 
 15 int ret;
 16 bool vis[N],vis_[N];
 17 void DFS_(int now)
 18 {
 19     if(now==0)
 20     {
 21         ret++;
 22         ret%=mod;
 23         return ;
 24     }
 25     for(int i=1; i<=m; ++i)
 26     {
 27         if(vis_[now-i]||(now-i<0)) continue;
 28         if(!vis[now-i]) continue;
 29         vis_[now-i]=1;
 30         DFS_(now-i);
 31         vis_[now-i]=0;
 32     }
 33 }
 34 void DFS(int now,int total)
 35 {
 36     if(now==total)
 37     {
 38         DFS_(now);
 39         return ;
 40     }
 41     for(int i=1; i<=n; ++i)
 42     {
 43         if(vis[now+i]||(now+i>tot)) continue;
 44         vis[now+i]=1;
 45         DFS(now+i,total);
 46         vis[now+i]=0;
 47     }
 48 }
 49 int work(int to)
 50 {
 51     ret=0;
 52     memset(vis,0,sizeof(vis));
 53     memset(vis_,0,sizeof(vis_));
 54     vis[0]=1; DFS(0,to);
 55     return ret;
 56 }
 57 
 58 int ret2;
 59 bool vis2[N];
 60 void dfs(int now,int x)
 61 {
 62     if(now==x)
 63     {
 64         ret2++;
 65         ret2%=mod;
 66         return ;
 67     }
 68     for(int i=1; i<=n; ++i)
 69     {
 70         if(now+i<=x) dfs(now+i,x);
 71     }
 72 }
 73 int work2(int x)
 74 {
 75     ret2=0;
 76     memset(vis2,0,sizeof(vis2));
 77     dfs(0,x);
 78     return ret2;
 79 }
 80 
 81 int AC()
 82 {
 83     freopen("stair.in","r",stdin);
 84     freopen("stair.out","w",stdout);
 85     
 86     int t; read(t);
 87     for(; t--; )
 88     {
 89         read(tot),read(n),read(m);
 90         memset(f,0,sizeof(f));
 91         memset(a,0,sizeof(a));
 92         for(int i=0; i<m; ++i) f[i]=work(i);
 93         for(int i=1; i<=m ;++i) a[i]=work2(i);
 94         for(int i=m; i<=tot; ++i)
 95             for(int j=1; j<=m; ++j)
 96             f[i]=(f[i]+f[i-j]*a[j])%mod;
 97         printf("%d\n",f[tot]);
 98     }
 99     return 0;
100 }
101 
102 int Hope=AC();
103 int main(){;}
考試的20分,46行的total被zz的我寫成tot啊啊啊,然後就TLE了。。沒用LL,啊啊啊

http://www.cnblogs.com/Shy-key/p/7484966.html 類似於這裏走樓梯的狀態方程。

f[i]+=f[i-j]*a[j],f[i]表示第一次走到i,第二次也走到i的方案數,

      a[j]表示第二次走到j,第一次可以走的方案數。

需要先預處理f[i]的初始值,以及第二次走i步,第一次可以走的方案數。

技術分享
  1 #include <cstring>
  2 #include <cstdio>
  3 
  4 #define LL long long
  5 
  6 const int mod(233333333);
  7 const int N(400000+626);
  8 int n,m,tot;
  9 LL a[N],f[N];
 10 
 11 inline void read(int &x)
 12 {
 13     x=0; register char ch=getchar();
 14     for(;ch>9||ch<0;) ch=getchar();
 15     for(;ch>=0&&ch<=9;ch=getchar()) x=x*10+ch-0;
 16 }
 17 
 18 int ret;
 19 bool vis[N],vis_[N];
 20 void DFS_(int now)
 21 {
 22     if(now==0)
 23     {
 24         ret++;
 25         ret%=mod;
 26         return ;
 27     }
 28     for(int i=1; i<=m; ++i)
 29     {
 30         if(vis_[now-i]||(now-i<0)) continue;
 31         if(!vis[now-i]) continue;
 32         vis_[now-i]=1;
 33         DFS_(now-i);
 34         vis_[now-i]=0;
 35     }
 36 }
 37 void DFS(int now,int total)
 38 {
 39     if(now==total)
 40     {
 41         DFS_(now);
 42         return ;
 43     }
 44     for(int i=1; i<=n; ++i)
 45     {
 46         if(vis[now+i]||(now+i>total)) continue;
 47         vis[now+i]=1;
 48         DFS(now+i,total);
 49         vis[now+i]=0;
 50     }
 51 }
 52 int work(int to)
 53 {
 54     ret=0;
 55     memset(vis,0,sizeof(vis));
 56     memset(vis_,0,sizeof(vis_));
 57     vis[0]=1; DFS(0,to);
 58     return ret;
 59 }
 60 
 61 int ret2;
 62 bool vis2[N];
 63 void dfs(int now,int x)
 64 {
 65     if(now==x)
 66     {
 67         ret2++;
 68         ret2%=mod;
 69         return ;
 70     }
 71     for(int i=1; i<=n; ++i)
 72     {
 73         if(now+i<=x) dfs(now+i,x);
 74     }
 75 }
 76 int work2(int x)
 77 {
 78     ret2=0;
 79     memset(vis2,0,sizeof(vis2));
 80     dfs(0,x);
 81     return ret2;
 82 }
 83 
 84 int AC()
 85 {
 86     freopen("stair.in","r",stdin);
 87     freopen("stair.out","w",stdout);
 88     
 89     int t; read(t);
 90     for(; t--; )
 91     {
 92         read(tot),read(n),read(m);
 93         memset(f,0,sizeof(f));
 94         memset(a,0,sizeof(a));
 95         for(int i=0; i<m; ++i) f[i]=work(i);
 96         for(int i=1; i<=m ;++i) a[i]=work2(i);
 97         for(int i=m; i<=tot; ++i)
 98             for(int j=1; j<=m; ++j)
 99             f[i]=(f[i]+f[i-j]*a[j])%mod;
100         printf("%I64d\n",f[tot]);
101     }
102     return 0;
103 }
104 
105 int Hope=AC();
106 int main(){;}
AC

無奈、

T3 勤勞的蜜蜂 UVa808

技術分享
 1 #include <cstdio>
 2 
 3 #define min(a,b) (a<b?a:b)
 4 int a,b,dis[1026][1026];
 5 
 6 int AC()
 7 {
 8     freopen("beehive.in","r",stdin);
 9     freopen("beehive.out","w",stdout);
10     
11     for(int i=1; i<=10; ++i)
12         for(int j=1; j<=10; ++j)
13         dis[i][j]=(i!=j)*0x3f3f3f3f;
14     for(int i=2; i<8; ++i) dis[1][i]=dis[i][1]=1;
15     for(int i=7; i<11; ++i) dis[2][i]=dis[i][2]=1;
16     dis[3][2]=dis[2][3]=dis[3][4]=dis[4][3]=dis[4][5]=dis[5][4]=1;
17     dis[5][6]=dis[6][5]=dis[6][7]=dis[7][6]=dis[7][8]=dis[8][7]=1;
18     dis[8][2]=dis[2][8]=dis[8][9]=dis[9][8]=1;
19     dis[9][2]=dis[9][10]=1;dis[3][10]=dis[10][3]=1;
20     for(int k=1; k<=10; ++k)
21       for(int i=1; i<=10; ++i)
22         for(int j=1; j<=10; ++j)
23           dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
24     for(; ~scanf("%d%d",&a,&b); )
25         printf("%d %d %d\n",a,b,dis[a][b]);
26     return 0;
27 }
28 
29 int Hope=AC();
30 int main(){;}
打表10分。棄療了

9.8——模擬賽