作者太巨辣!
%%%乔猫
好。
ZJ一下:
哭笑不得。
T1直接审错题(没发现题目里那个憨P的更新限制),然后直接跑了$mathsf{SPFA}$,然后我又发现了。以为我死了,结果手玩一下发现……那句话没有用……
试图卡一下$mathsf{SPFA}$但是发现卡不掉,我想这么水一题卡毛线$mathsf{SPFA}$,于是就扔掉了。
T2打了贪心错解组合版,但是自己大力$ ext{hack}$完后就以为死了,后来还有$30pts$,作者太友好了(感动
T3发现直接在角度上维护即可,于是码完,然后发现给的端点真不友好,不是左上右下,而是左下右上,后来还被卡精了$ ext{kuku}$
这是TJ:
T1:
名正言顺的AC了。
作者没有构造卡$mathsf{SPFA}$的数据……
很不明白网格图上咋卡……
#include <iostream> #include <cstring> #include <cstdio> #define N 555 using namespace std; const int mx[]={0, 0,1,-1}, my[]={1,-1,0, 0}; typedef pair<int,int> pii; template<typename T> class Myqueue{ T A[N*N*100]; int f,b; public: Myqueue(){f=b=0;} void clear(){f=b=0;} void push(const T k){A[b++]=k;} void pop(){f++;} T front(){return A[f];} bool empty(){return f==b;} }; Myqueue<pii>q; int lines,cols; int tps[N][N],lps[N][N]; int fix,fiy; bool inq[N][N]; void pour(){ for(int i=1;i<=3;i++){ for(int j=1;j<=cols;j++){ cout<<"----"; } if(i!=3)cout<<"+"; } puts(""); for(int i=1;i<=lines;i++){ for(int j=1;j<=cols;j++) printf("%4d",lps[i][j]); cout<<"|"; for(int j=1;j<=cols;j++) printf("%4d",tps[i][j]); cout<<"|"; for(int j=1;j<=cols;j++) printf("%4d",inq[i][j]); puts(""); } /* puts("------Inqueue----------"); for(int i=1;i<=lines;i++){ for(int j=1;j<=cols;j++){ printf("%4d",inq[i][j]); }puts(""); }*/ } inline bool in_b(int x,int y){ return x>=1&&x<=lines&&y>=1&&y<=cols; } inline bool in_b(pii ps){ return in_b(ps.first,ps.second); } void bfs(int x,int y){//? q.push(make_pair(x,y)); inq[x][y]=1; while(!q.empty()){ int fx=q.front().first, fy=q.front().second; // cout<<fx<<" "<<fy<<endl; q.pop(); if(q.empty())q.clear(); inq[fx][fy]=0;//?Double UPD?? for(int i=0;i<4;i++){ int tx=fx+mx[i], ty=fy+my[i]; if(in_b(tx,ty) && lps[tx][ty]<lps[fx][fy]-tps[tx][ty]){ lps[tx][ty]=lps[fx][fy]-tps[tx][ty]; if(!inq[tx][ty]){ q.push(make_pair(tx,ty)); inq[tx][ty]=1; } } } // pour(); } } int main(){ // freopen("neworld.in" ,"r",stdin); freopen("neworld.out","w",stdout); int a,b,c; scanf("%d%d",&lines,&cols); for(int i=1;i<=lines;i++) for(int j=1;j<=cols;j++) scanf("%d",&tps[i][j]); scanf("%d%d%d%d%d",&a,&b,&c,&fix,&fiy); lps[a][b]=c; bfs(a,b); printf("%d ",lps[fix][fiy]); // cerr<<clock()<<endl; }
叫$mathsf{BFS}$但是是$mathsf{SPFA}$
T2:
状压即可,细节还行。
#include <iostream> #include <cstring> #include <climits> #include <cstdio> //#include "debug.h" #define N 111 #define M 10 #define S (1<<9)+10 using namespace std; int dp[N][S],mp[N]; int lines,cols,maxs; inline int lowbit(int x){ return x&(-x); } inline int count(int x){ int n_1=0; while(x){ x-=lowbit(x); n_1++; } return n_1; } bool is_ok(int i1,int pos1){ for(int i=1;i<=cols;i++){ int j=1<<(i-1); if(j&pos1){ if(!(j&mp[i1]))return false; } } for(int i=1;i<=cols;i++){ int j=1<<(i-1); if((j&mp[i1])&&(!((j>>1)&mp[i1]))){ if(!(j&pos1))return false; } } return true; } int get_merge(int i1,int pos1,int i2,int pos2){ int dat=0; for(int i=1;i<=cols;){ int j=1<<(i-1); // cout<<i<<" Outout"<<endl; if((pos1&j) && (pos2&j)){ int k=i+1,l=1<<(k-1); while(1){ //cerr<<k<<endl; if(k>cols){ dat++; break; } if(((!(l&mp[i1])) || (l&pos1)) && ((!(l&mp[i2])) || (l&pos2))){ // puts("All WA"); dat++; break; } else if( (l&mp[i1])&&(l&mp[i2])&&(!(l&pos1))&&(!(l&pos2)) ){ //puts("One WA"); k++,l=1<<(k-1); } else break; //puts("Contined"); } i=k; continue; } i++; } // cout<<"Res:"<<dat<<endl; return dat; } int main(){ ios_base::sync_with_stdio(false); int a; cin>>lines>>cols; maxs=(1<<cols)-1; for(int i=1;i<=lines;i++){ for(int j=1;j<=cols;j++){ cin>>a; mp[i]|=a<<(j-1); } } // for(int i=1;i<=lines;i++)\ cerr<<bin(mp[i],cols)<<endl; memset(dp,0x3f,sizeof dp); for(int s=0;s<1<<cols;s++){ if(is_ok(1,s)){ dp[1][s]=count(s); // cerr<<dp[1][s]<<" "<<bin(s,cols)<<endl; } } for(int i=2;i<=lines;i++){ for(int s=0;s<1<<cols;s++){ if(!is_ok(i,s))continue; for(int t=0;t<1<<cols;t++){ if(!is_ok(i-1,t))continue; //cerr<<"Mp["<<i<<"]="<<bin(mp[i],cols) <<" S:"<<bin(s,cols)<<" " <<"Mp["<<i-1<<"]="<<bin(mp[i-1],cols) <<" T:"<<bin(t,cols)<<endl; int val=count(s)-get_merge(i,s,i-1,t); // cout<<"val:"<<get_merge(i,s,i-1,t)<<endl; dp[i][s]=min(dp[i][s], dp[i-1][t]+val); // cout<<"dp["<<i<<"]["<<bin(s,cols)<<"]="<<dp[i][s]<<endl; } } } int ans=INT_MAX; for(int s=0;s<1<<cols;s++) if(is_ok(lines,s)) ans=min(ans,dp[lines][s]); cout<<ans<<endl; }
T3:
不会!