XJOJ - 路径数(最短路+最短路路径数量)
題目鏈接:點(diǎn)擊查看
題目大意:Euphemia到一個(gè)N*N的藥草田里采藥,她從左上角的格子田(第一行,第一列)出發(fā),要到達(dá)右下角(第N行,第N列)的格子田,每次她可以走到與當(dāng)前格子有邊相鄰的格子去,但她不會走已經(jīng)走過的格子,而且出于對美的要求,她走過的路徑是關(guān)于 左下-右上 對角線對稱的。由于地勢不同,在每個(gè)格子田采藥都會有一個(gè)疲勞度Tij,Euphemia想知道:有多少條合法路徑,可以使得她采藥的疲勞度最小。
輸入格式:
多組數(shù)據(jù)。
每組數(shù)據(jù)第一行一個(gè)整數(shù)N,接下來N行,每行N個(gè)非零數(shù)字(1,2,3...9中一個(gè)),表示格子田的疲勞度。
當(dāng)N=0,輸入結(jié)束。
?
輸出格式:
對于每組數(shù)據(jù),輸出一個(gè)整數(shù)表示答案,答案%1000000009。
?
樣例輸入:
2 1 1 1 1 3 1 1 1 1 1 1 2 1 1 0?
樣例輸出:
2 3?
數(shù)據(jù)范圍:
對于20%的數(shù)據(jù)滿足N<=5。
對于另外20%的數(shù)據(jù)滿足N<=40。
對于100%的數(shù)據(jù)滿足N<=100,不超過50組數(shù)據(jù)。
?
時(shí)間限制:
1S
?
空間限制:
256M
?
題目分析:因?yàn)橐P(guān)于副對角線對稱,所以不妨直接將矩陣沿著副對角線對折,因?yàn)橐笞疃搪?#xff0c;所以不妨直接求出以點(diǎn)(1,1)為起點(diǎn)的單源最短路,期間用dp維護(hù)一下最短路路徑的數(shù)量,最后累加一下就好了,這個(gè)dp我是直接從網(wǎng)上拿的模板,迪杰斯特拉+dp
代碼:
#include<iostream> #include<cstdio> #include<string> #include<ctime> #include<cmath> #include<cstring> #include<algorithm> #include<stack> #include<climits> #include<queue> #include<map> #include<set> #include<sstream> using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=110;const int mod=1e9+9;const int b[4][2]={0,1,0,-1,1,0,-1,0};int maze[N][N],n;bool vis[N][N];int d[N][N];LL dp[N][N];struct Node {int x,y,w;Node(int X,int Y,int W){x=X;y=Y;w=W;}bool operator<(const Node& a)const{return w>a.w;} };void Dijkstra() {priority_queue<Node>q;memset(vis,false,sizeof(vis));memset(d,inf,sizeof(d));memset(dp,0,sizeof(dp));dp[1][1]=1;d[1][1]=maze[1][1];q.push(Node(1,1,d[1][1]));while(q.size()){Node cur=q.top();int x=cur.x,y=cur.y;q.pop();if(vis[x][y])continue;vis[x][y]=true;for(int i=0;i<4;i++){int xx=x+b[i][0];int yy=y+b[i][1];if(xx<=0||yy<=0||xx>n||yy>n||xx+yy>n+1)continue;int w=maze[xx][yy];if(d[xx][yy]>d[x][y]+w){d[xx][yy]=d[x][y]+w;dp[xx][yy]=dp[x][y];q.push(Node(xx,yy,d[xx][yy]));}else if(d[xx][yy]==d[x][y]+w)dp[xx][yy]=(dp[xx][yy]+dp[x][y])%mod;}} }int main() { #ifndef ONLINE_JUDGE // freopen("input.txt","r",stdin); // freopen("output.txt","w",stdout); #endif // ios::sync_with_stdio(false);while(scanf("%d",&n)!=EOF&&n){for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)scanf("%d",&maze[i][j]);for(int i=1;i<=n;i++)for(int j=1;j<n-i+1;j++)maze[i][j]+=maze[n-j+1][n-i+1];Dijkstra();int mmin=inf;//找出最短路for(int i=1;i<=n;i++)mmin=min(mmin,d[i][n-i+1]); LL ans=0;//維護(hù)答案for(int i=1;i<=n;i++)if(d[i][n-i+1]==mmin)ans=(ans+dp[i][n-i+1])%mod;printf("%lld\n",ans);}return 0; }?
總結(jié)
以上是生活随笔為你收集整理的XJOJ - 路径数(最短路+最短路路径数量)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 牛客 - 仓库选址(中位数+思维)
- 下一篇: CodeForces - 1313C2