從西向東依次給出 \(n\) 座城市,和這 \(n\) 座城市中的 \(m\) 條邊,求出滿足下列條件的旅行路徑:
從這道題的題面再結合範圍非常有限的 \(n\) ,很容易想到可以用網路流來解決。
那麼下面考慮如何建圖:
首先由於每乙個點只能被經過一次,那我們可以用到乙個非常常見的手法,就是拆點,將 \(i\) 拆成 \(i\) 和 \(i+n\) 兩個點,再在這兩個點之間連上一條流量為 \(1\) ,費用為 \(1\) 的點。
而對於 \(m\) 條邊,假設 \(i\) 為每個城市 \(i\) 的入點, \(i+n\) 為城市 \(i\) 的出點,則我們只需要將西邊城市的出點向東邊城市的入點連一條流量為 \(1\) ,費用為 \(0\) 的邊即可。那麼為什麼流量為 \(1\) 呢,其實理論上來講,這裡的流量設為 \(inf\) 也是可以的,但是為了方便之後的輸出路徑,可以直接找到殘次圖中 \(w[i]=0\) 的邊,所以我們這裡將其設定為 \(1\) 。
然後再用到網路流的慣用伎倆,建立超級源點和超級匯點,分別與最西邊的城市的入點和最東邊的城市的出點連邊即可,流量都可以設定為\(inf\)。
但是上述建圖只實現了單邊過程,如何返回?
其實我們只需要將最西邊城市和最東邊城市的兩個拆點之間的流量改為 \(2\) 即可,這也就意外這我們可以找到兩條流量為 \(1\) 的增廣路,恰對應來回兩個過程。
這樣建完圖之後再跑一次最大費用。
最後怎麼輸出。
我們只需要兩次 \(dfs\) ,第一次輸出去的過程,找到一條殘次圖中 \(w[i]=0\) 的路徑正序輸出,第二次輸出回的過程,找到另一條殘次圖中 \(w[i]=0]\) 的路徑,但是這次換為倒序輸出。
那這樣這道題就做完了。
值得注意的是,這道題是有乙個特殊情況的。
正常情況下,我們用 \(ek\) 演算法跑最大費用,則進行兩次,就意味著找到了兩條路徑。但是如果考慮我們只有一條從最西端的城市連向最東端城市的可行路徑,則按照上述建圖過程,他只能找到一條路徑。這樣一來,我們就需要加上乙個特殊判斷,也就是如果有一條起點和終點的連邊且只找到一條路徑(我們就能夠確認只有這一種最壞的情況了,因為這種情況確實是可行方案中經過城市數量最少的,如果有其他方案,就不會使用它),則直接輸出三個字串,第乙個城市的名稱,最後乙個城市的名稱,第乙個城市的名稱。
#include using namespace std;
const int n=1e2+10,m=5e3+10,inf=0x7fffffff;
int n,m,s,t,ans,tim;
char ss[n][20];
mapmp;
inline int read()
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;
}int tot=-1,v[m*2+n*2],w[m*2+n*2],p[m*2+n*2],nex[m*2+n*2],first[n*2];
inline void add(int x,int y,int z,int c)
bool vis[2*n];
int pre[2*n],dis[2*n],min[2*n];
inline bool spfa()
} }return dis[t]!=-1;
}inline void ek() }}
inline void dfs1(int x) //第一次正序,為去的過程
}inline void dfs2(int x)
add(s,1,inf,0),add(1,s,0,0);
add(2*n,t,inf,0),add(t,2*n,0,0);
for(register int i=1;i<=n;i++)
ek();
if(tim==2) printf("%d\n",ans-2); //重複計算1,n
else if(tim==1&&flag) //明顯只有首尾相連這條線路
else
memset(vis,false,sizeof(vis));
dfs1(1+n),dfs2(1+n); //輸出答案
return 0;
}
網路流24題 航空路線問題
題目描述 給定一張航空圖,圖中頂點代表城市,邊代表 2 城市間的直通航線。現要求找出一條滿足下述限制條件的且途經城市最多的旅行路線。1 從最西端城市出發,單向從西向東途經若干城市到達最東端城市,然後再單向從東向西飛回起點 可途經若干城市 2 除起點城市外,任何城市只能訪問 1 次。從東到西到達乙個點...
網路流 24 題 航空路線問題
題目描述 給定一張航空圖,圖中頂點代表城市,邊代表兩個城市間的直通航線。現要求找出一條滿足下述限制條件的且途經城市最多的旅行路線。從最西端城市出發,單向從西向東途經若干城市到達最東端城市,然後再單向從東向西飛回起點 可途經若干城市 除起點城市外,任何城市只能訪問一次。對於給定的航空圖,試設計乙個演算...
網路流24題 航空路線問題
乙個點只能經過一次 拆點,連流量為1,費用為0的邊。最多能經過多少城市 最大費用流。兩個點之間有一條路線 從u 連向v。這種題一般都這樣建邊 需要注意的一點是 第二個測試點它的最佳方案是從1到n然後再到1 所以不能對於每條可行的線路的容量設定成1,這樣的話對於這種情況就無法回來了qwq ifndef...