8.3.4 奧運

奧運

Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 82 Accepted Submission(s): 40

Problem Description
北京迎來了第一個奧運會,咱們的歡呼聲響徹中國大地,因此今年的奧運金牌 day day up!
比爾蓋茲坐上鳥巢裏,手裏搖着小紙扇,看的不亦樂乎,被俺們健兒的頑強拼搏的精神深深的感動了。反正個人錢也多的沒地方放了,他對本身說,我本身也來舉辦一個奧運會,看誰的更火。不過他的奧運會很特別:
1 參加人員必須是中國人;
2 至少會加法運算(由於要計算本人得到的金牌數)
他 知道中國有不少的名勝古蹟,他知道本身在t1 到 t2天內不可能把全部的地方都玩遍,因此他決定指定兩個地方v1,v2,若是參賽員能計算出在t1到t2天(包括t1,t2)內從v1到v2共有多少種走 法(每條道路走須要花一天的時間,且不能在某個城市停留,且t1=0時的走法數爲0),那麼他就會得到相應數量的金牌,城市的總數<=30,兩個城 市間能夠有多條道路
,每條都視爲是不一樣的。
 

Input
本題多個case,每一個case:
輸入一個數字n表示有n條道路 0<n<10000
接下來n行每行讀入兩個數字 p1,p2 表示城市p1到p2有道路,並不表示p2到p1有道路 (0<=p1,p2<2^32)
輸入一個數字k表示有k個參賽人員
接下來k行,每行讀入四個數據v1,v2,t1,t2 (0<=t1,t2<10000)
 

Output

            對於每組數據中的每一個參賽人員輸出一個整數表示他得到的金牌數(mod 2008)
 

Sample Input
6
1 2
1 3
2 3
3 2
3 1
2 1
3
1 2 0 0
1 2 1 100
4 8 3 50
 

Sample Output
0
1506
0

思路:用map和鄰接矩陣spa

路徑條數就是把鄰接矩陣乘起來設計

想一想爲何?code

咱們怎麼計算路徑條數?blog

假設計算到a的路徑條數=sigma({集合b:全部能到達a的點}的路徑條數*(集合b的每個對應元素到a)有多少條路)ip

  1 #include <cmath>
  2 #include <cstdio>
  3 #include <algorithm>
  4 #include <cstring>
  5 #include <string>
  6 #include <cstdlib>
  7 #include <map>
  8 using namespace std;
  9 
 10 typedef long long ll;
 11 typedef double dd;
 12 const int maxn=10010;
 13 const int mod=2008;
 14 map<int,int> mp;
 15 int n,v1,v2,V1,V2,query,T,t1,t2,m,x,y,ans;
 16 struct matrix
 17 {
 18     int m[31][31];
 19 } c,r[maxn],base;
 20 
 21 void close()
 22 {
 23 exit(0);
 24 }
 25 
 26 void print(matrix a)
 27 {
 28     for (int i=1;i<=n;i++)
 29     {
 30         for (int j=1;j<=n;j++)
 31             printf("%d ",a.m[i][j]);
 32         puts("");
 33     }
 34 }
 35 
 36 matrix mul(matrix a,matrix b)
 37 {
 38     memset(c.m,0,sizeof(c.m));
 39     for (int i=1;i<=n;i++)
 40         for (int j=1;j<=n;j++)
 41             for (int k=1;k<=n;k++)
 42             {
 43                 c.m[i][j]+=a.m[i][k]*b.m[k][j];
 44                 c.m[i][j] %= mod;
 45             }
 46     return c;
 47 }
 48 
 49 void init()
 50 {
 51 
 52 }
 53 
 54 int main ()
 55 {
 56     while (scanf("%d",&T)!=EOF)
 57     {
 58         n=0;
 59         mp.clear();
 60         memset(base.m,0,sizeof(base.m));
 61         while (T--)
 62         {
 63             scanf("%d %d",&x,&y);
 64             if (mp[x]==0)
 65             {
 66                 n++;
 67                 mp[x]=n;
 68             }
 69             if (mp[y]==0)
 70             {
 71                 n++;
 72                 mp[y]=n;
 73             }
 74             base.m[mp[x]][mp[y]]++;
 75             // X -> Y
 76         }
 77         m=10000; //Need to be changed!
 78         r[1]=base;
 79         for (int i=2;i<=m;i++)
 80             r[i]=mul(r[i-1],base);
 81         scanf("%d",&query);
 82         while (query--)
 83         {
 84             ans=0;
 85             scanf("%d %d %d %d",&v1,&v2,&t1,&t2);
 86             if (t1>t2 || t2==0)
 87             {
 88                 ans=0;
 89             }
 90             else
 91             {
 92                 if (mp[v1]==0 || mp[v2]==0)
 93                     ans=0;
 94                 else
 95                 {
 96                     V1=mp[v1];
 97                     V2=mp[v2];
 98                     for (int i=max(1,t1);i<=t2;i++)
 99                     {
100 
101                         ans+=r[i].m[V1][V2];
102                         ans %= mod;
103                     }
104                 }
105             }
106             printf("%d\n",ans);
107         }
108     }
109     return 0;
110 }
相關文章
相關標籤/搜索