POJ 1062
阿新 • • 發佈:2019-02-11
1.Question:
中文題不說什麼了2.Solution:
本題的難點有兩個 1.建圖 2.限制 建圖: 首先,我們需要明確本圖G是一個有向圖,我們的頂點代表廟我們的物品的編號,圖採用鄰接矩陣儲存,我們的圖中的鄰接矩陣中儲存我們的便宜價格這樣的話,我們每個點只要在限制條件下都可以找到1點,那麼我們就取到達1點的最小值當作我們的答案 限制: 本體的限制說的很明確,但是我們如何處理我們的限制確實非常的苦難,網上的大神采用了區間列舉的思路,我們對SPFA進行操作的時候,我們的鬆弛百年志鬆馳在限制區間範圍的邊才可以 另外,通過本體需要學會一種叫做超級源點的思路,我們的0視作超級源點,該點和其他的點之間的都有連邊,連邊的長度大小是我們的該點除的物品的權值,超級源點的思路非常的有用3.Code:
/* Problem: 1062 User: lantianheyeqi Memory: 240K Time: 32MS Language: C++ Result: Accepted */ #include"iostream" #include"cstdio" #include"cstring" #include"cstdlib" #include"cmath" #define N 0x3f3f3f3f int n,m; int map[105][105]; int l[105]; void init_map() { for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(i!=j) map[i][j]=N; else map[i][j]=0; } } } int SPFA(int j,int k) { int queue[100*100]; int head=1; int tail=2; bool book[105]; memset(book,0,sizeof(book)); book[0]=1; queue[1]=0; int dis[105]; for(int i=1;i<=n;i++) dis[i]=N; dis[0]=0; while(head!=tail) { for(int i=1;i<=n;i++) { if(l[i] < j || l[i] > k) continue; if(dis[i] > dis[queue[head]]+map[queue[head]][i]) { dis[i] = dis[queue[head]]+map[queue[head]][i]; if(book[i]==0) { book[i]=1; queue[tail++]=i; } } } book[queue[head]]=0; head++; } return dis[1]; } int main() { scanf("%d%d",&m,&n); init_map(); for(int i=1;i<=n;i++) { int x,y,z; scanf("%d%d%d",&x,&y,&z); map[0][i]=x; l[i]=y; for(int j=1;j<=z;j++) { int number,money; scanf("%d%d",&number,&money); map[number][i]=money; } } int mink=N; for(int i=l[1]-m;i<=l[1];i++) { int w=SPFA(i,i+m); if(w<mink) mink=w; } printf("%d\n",mink); return 0; }