模擬賽直接昇天 ios
100 + 100 + 100 + 30 秒變 50 + 30 + 0 + 30數組
自身的問題仍是有點多ide
有一張 n 個點, m條邊的無向圖,點從 1到 n標號。ui
時刻 0時,你在結點1 。你須要用最少的時間從結點 1走到結點n 。經過m條邊中的每一條都要花必定的時間。spa
每一個結點會有可能在某些時刻被限制。一個結點 x 在時刻T被限制,意味着這個結點的人在時刻T不能從這個點x走出去。3d
你只能在整數時刻進出某個結點,一個結點能夠逗留任意非負整數時間。code
如今,請問你最少須要多少時間能從結點 1走到結點n 。blog
能夠看出確定越早到一個點越優 在這個點上等再到這個點的全部連點 和 到連點後再等待出點 是同一個道理,咱們記錄每一個點的最先到達時間,遊戲
用最先出點時間更新它的連點 跑一遍最短路就好了 同時 數組 須要 開大 且 開始定義的最大值要很大 否則直接wa了。it
#include <iostream> #include <cstdio> #include <queue> #include <algorithm> #define f(i, a, b) for (long long i = a; i <= b; i++) using namespace std; priority_queue<pair<long long, long long> > QAQ; long long n, m, k, begi, fina, v, head[100100], d[100100]; bool tim[5000][5000]; bool visit[100010]; struct QWQ { long long to, next, value; } edge[100100]; void make(long long a, long long b, long long c) { edge[++edge[0].value].to = b; edge[edge[0].value].value = c; edge[edge[0].value].next = head[a]; head[a] = edge[0].value; } void dij() { QAQ.push(make_pair(0, 1)); d[1] = 0; while (QAQ.size()) { long long num = QAQ.top().second; QAQ.pop(); if(visit[num]) continue; visit[num] = 1; long long p = d[num]; while(tim[num][p])p++; for (long long i = head[num]; i; i = edge[i].next) { if (p + edge[i].value < d[edge[i].to]) { d[edge[i].to] = p + edge[i].value; QAQ.push(make_pair(-d[edge[i].to], edge[i].to)); } } } } int main() { freopen("travel.in", "r", stdin); freopen("travel.out", "w", stdout); scanf("%lld%lld", &n, &m); f(i, 1, m) { scanf("%lld%lld%lld", &begi, &fina, &v); make(begi, fina, v); make(fina, begi, v); } f(i, 1, n) { scanf("%lld", &k); long long t; f(j, 1, k) { scanf("%lld", &t); tim[i][t] = 1; } d[i] = 1e16; } dij(); printf("%lld", d[n]); return 0; }
#include<cstdio> #include<algorithm> using namespace std; const long long mo=998244353; const int MAXN=100000+5; long long a[MAXN],inv[MAXN],fact[MAXN]; long long power(long long a,long long b) { long long t=1,y=a%mo; while (b) { if (b&1) t=t*y%mo; y=y*y%mo; b>>=1; } return t; } int main() { freopen("card.in","r",stdin); freopen("card.out","w",stdout); int n,k; scanf("%d%d",&n,&k); for (int i=1;i<=n;i++) scanf("%d",&a[i]); fact[0]=inv[0]=1; for (int i=1;i<=n;i++) { fact[i]=fact[i-1]*i%mo; inv[i]=power(fact[i],mo-2); } int sum; long long ans=0; for (int i=0;i<=30;i++) { sum=0; for (int j=1;j<=n;j++) sum+=((a[j]>>i)&1); for (int j=1;j<=min(k,sum);j++) if (k-j<=n-sum&&j&1) ans=(ans+fact[sum]*inv[j]%mo*inv[sum-j]%mo*fact[n-sum]%mo*inv[k-j]%mo*inv[n-sum-k+j]%mo*(1ll<<i)%mo)%mo; } printf("%lld",ans); return 0; }
C D 待續