【NOIP2017模擬賽】思維+轉化+圖論 徒然Children(好題)
題目描述
全世界都在談戀愛,只有我深愛著學習。——前言。
2333身為單身狗卻意外喜歡的吃狗糧的yuki堅信著:“自古紅藍出cp,黑白天生是夫妻,最是銷魂紅綠配,天然金紫成雙對,生死相隨紅與黃,白紫一逢春滿堂,千里緣牽白與綠,紅黑生來為相聚。”的cp配對原則,卻被徒然children中綠黃的御宅的春天組(山根隆夫×慄原千代)莫名戳中萌點。可見死宅真是一個有前途的職業。在本季末尾,一群cp們正在舉行足球賽,想要偷懶的可愛死宅山根隆夫卻聽到了更可愛的慄原千代的加油聲,他感到很無奈,想要在操場上選擇一些不需要跑動的地方偷懶,又不想太過明顯影響在妹子心中的形象。操場是一個n*n方格矩陣,每一個格子上有一個非負整數A(i,j)表示山根隆夫停在這裡會在慄原千代心中減多少分,他希望在操場中選若干格子歇息,B(i,j)=1表示格子(i,j)被選中,B(i,j)=0表示格子(i,j)未被選中。矩陣B必須滿足三個條件山根隆夫才不會被紅牌下場。
身為死宅的你,一定也有著和超級可愛的死宅山根隆夫一樣的關於妹子的理想。那麼請你幫幫他,找出一種方案使他在妹子心中減的分最少。
輸入
第一行一個整數n表示操場的大小,n行n列的格子。接下來n行每行n各整數表示A(i,j)。
輸出
一行一個整數表示山根隆夫在可愛的慄原千代心中最少減了多少分。
樣例輸入
5
7 2 3 6 1
5 2 6 9 4
4 2 1 5 3
4 6 9 8 5
1 4 4 5 2
樣例輸出
1
對於前10%的資料:n<=10
對於前20%的資料:n<=100
對於前50%的資料:n<=1000
對於100%的資料:n<=2000
題解
初看題面,你會覺得這道題很難,然後去思考各種各樣的數學方法,或者一些詭異的亂搞的方法。
其實,如果你仔細看這道題,它其實是一道圖論模板(驚歎
如果把
仍然是沒有註釋的程式碼,抱歉啦~
#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 2005
#define ll long long
int n,vis[N];
ll A[N][N],dis[N],ans,rnd=1ll<<60;
queue<int>q;
ll getll()
{
ll p=0;char c=getchar();
while(c<'0'||c>'9')
c=getchar();
while(c>='0'&&c<='9')
p=p*10+c-'0',c=getchar();
return p;
}
void putll(ll a)
{
if(a<0)putchar('-'),a=-a;
if(a>9)putll(a/10);
putchar(a%10+'0');
}
void SPFA(int s)
{
for(int i=0;i<=n;i++)
dis[i]=1ll<<60;
dis[s]=0;
q.push(s);
while(!q.empty())
{
int x=q.front();q.pop();
for(int i=1;i<=n;i++)
{
if(dis[x]+A[x][i]<dis[i])
{
dis[i]=dis[x]+A[x][i];
if(!vis[i])
{
vis[i]=1;
q.push(i);
}
}
}
vis[x]=0;
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
A[i][j]=getll();
SPFA(1);
ans=dis[n];
for(int i=2;i<=n;i++)
rnd=min(rnd,dis[i]+A[i][1]);
SPFA(n);
for(int i=1;i<n;i++)
ans=min(ans,rnd+dis[i]+A[i][n]);
putll(ans);
putchar(10);
}