星期一:
牛客寒假训练营2,打的一般,会做的都做了,但做了的也都是一眼能做的.
星期二:
补题:
思路:用的dij,貌似dp也行
下标1到n,超过需要模时,可以减一,模n,再加一
ve[i].push_back({b[j],(i+a[j]-1)%n+1});
因为优先队列用的PII所以爆int了,以后注意
代码如下:
ll n;
int m,k;
int a[1010],b[1010];
vector<PII>ve[5050];
bool vi[5050];
ll dis[5050];
void dij(){
priority_queue<PII,vector<PII>,greater<PII>>pq;//pair<ll,ll>
for(int i=0;i<5010;i++) dis[i]=LLONG_MAX;
dis[k]=0;
pq.push({0,k});
while(pq.size()){
auto [d,t]=pq.top(); pq.pop();
if(vi[t]) continue;
vi[t]=1;
for(auto [x,y]:ve[t]){
if(x+dis[t]<dis[y]){
dis[y]=x+dis[t];
pq.push({dis[y],y});
}
}
}
}
void solve(){
cin >> n >> m >> k;
for(int i=1;i<=m;i++){
cin >> a[i] >> b[i];
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
ve[i].push_back({b[j],(i+a[j]-1)%n+1});
}
}
dij();
if(dis[n]==LLONG_MAX) cout << "-1\n";
else cout << dis[n] << "\n";
for(int i=0;i<=n;i++) ve[i].clear(),vi[i]=0;
}
星期三:
牛客训练营3,打的依托
星期四:
补补cf的题
题意:找到一个环包含最小边,输出环的遍历路径
思路:用并查集判断环,dfs找路
代码如下:
const int N=2e5+10;
const int mod=1e9+7;
ll n;
struct nod{
int u,v,w;
}e[N];
int m;
int uu,vv,ww;
int fa[N];
bool vi[N];
vector<PII>ve[N];
vector<int>pa;
bool cmp1(nod a,nod b){
return a.w>b.w;
}
int fnd(int x){
return fa[x]==x?x:fa[x]=fnd(fa[x]);
}
int dfs(int x){
if(x==vv) return 1;
for(auto [v,w]:ve[x]){
if(vi[v] || w<ww) continue;
pa.push_back(v);
vi[v]=1;
if(dfs(v)) return 1;
pa.pop_back();
}
return 0;
}
void solve(){
cin >> n >> m;
for(int i=1;i<=n;i++) fa[i]=i;
for(int i=1;i<=m;i++){
cin >> e[i].u >> e[i].v >> e[i].w;
}
sort(e+1,e+m+1,cmp1);
for(int i=1;i<=m;i++){
int u=e[i].u,v=e[i].v,w=e[i].w;
ve[u].push_back({v,w}),ve[v].push_back({u,w});
int fu=fnd(u),fv=fnd(v);
if(fu==fv) uu=u,vv=v,ww=w;
else fa[fu]=fv;
}
pa.push_back(uu);
vi[uu]=1;
dfs(uu);
cout << ww << " " << pa.size() << "\n";
for(auto i:pa) cout << i << " ";
cout << "\n";
for(int i=1;i<=n;i++) ve[i].clear(),vi[i]=0;
pa.clear();
}
round 923(div3) 压台的dp
题意:自行理解
思路:dp [ i ][ j ][ k ]表示考虑到 a[ i ]时左数第一个没涂色的和从i往右数第一个没涂色的,n3做法
代码如下:
const int N=2e5+10;
const int mod=1e9+7;
ll n;
int a[110];
int dp1[110][110],dp2[110][110];
void solve(){
cin >> n;
for(int i=1;i<=n;i++){
cin >> a[i];
}
for(int i=0;i<=n+1;i++){
for(int j=0;j<=n+1;j++)
dp1[i][j]=dp2[i][j]=1e9;
}
dp1[1][1]=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=n+1;j++){
for(int k=max(i,j);k<=n+1;k++){
dp2[j][k+(k==i)]=min(dp1[j][k],dp2[j][k+(k==i)]);
int le=max(1,i-a[i]+1);
if(le<=j){
dp2[k+(k==i)][k+(k==i)]=min(dp1[j][k]+1,dp2[k+(k==i)][k+(k==i)]);
}
int ri=min(n,1ll*i+a[i]-1);
if(ri>=k){
if(j>=i){
dp2[ri+1][ri+1]=min(dp1[j][k]+1,dp2[ri+1][ri+1]);
}else{
dp2[j][ri+1]=min(dp1[j][k]+1,dp2[j][ri+1]);
}
}
}
}
for(int j=0;j<=n+1;j++){ //滚动
for(int k=0;k<=n+1;k++)
dp1[j][k]=dp2[j][k],dp2[j][k]=1e9;
}
}
cout << dp1[n+1][n+1] << "\n";
}
星期五:
玩了一天文明6,种田,爽 !
星期六:
回老家,去亲戚家吃了两顿饭
写个floyd板子
void floyd(){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(i==j) dp[i][j]=0;
else dp[i][j]=1e9;
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++)
for(int k=1;k<=n;k++)
dp[j][k]=min(dp[i][j]+dp[i][k],dp[j][k]);
}
}