【Floyed】【匈牙利算法】导弹(jzoj 1610)
生活随笔
收集整理的這篇文章主要介紹了
【Floyed】【匈牙利算法】导弹(jzoj 1610)
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
題目大意:
有n個(gè)城市,有一部分是A國(guó)的,有一部分是B國(guó)的(小于A國(guó)的),A國(guó)每個(gè)城市都有一枚導(dǎo)彈(只有一枚),炸毀別的城市的時(shí)間是到這個(gè)城市的距離,請(qǐng)問A國(guó)最快要多久可以炸毀B國(guó)所有城市
解題思路:
先用Floyed來求出最短路,然后二分枚舉答案再用匈牙利算法確認(rèn)是否可以,即可
代碼
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> using namespace std; int bg[105],head[105],a[105][105],b[105],c[105],w,sum,l,r,mid,n,m,nm; bool pd[105]; struct rec {int to,next; }f[10005];//每一條路線 bool js(int xx) {int l=0;for (int i=head[xx];i;i=f[i].next)//連接此點(diǎn)的每一條線if (!pd[f[i].to])//可以搶{l=bg[f[i].to];//之前是誰(shuí)打的bg[f[i].to]=xx;//代替pd[f[i].to]=true;//不能搶了if ((!l)||(js(l))) return true;//之前沒人或搶到了bg[f[i].to]=l;//沒法打這個(gè)城市就還給之前的}return false;//找不到可以打的 } bool sj(int now) {memset(head,0,sizeof(head));//清零memset(bg,0,sizeof(bg));//清零w=0;//清零sum=0;//清零for (int i=1;i<=n;i++)for (int j=1;j<=m;j++)if (a[b[i]][c[j]]<=now)//判斷是否少于當(dāng)前的時(shí)間{f[++w].to=j;//下一個(gè)點(diǎn)f[w].next=head[i];//下一條線head[i]=w;//這個(gè)點(diǎn)的第一條線} for (int i=1;i<=n;i++){memset(pd,false,sizeof(pd));//清零if (js(i)) sum++;//判斷是否能打到敵人}return sum==m;//判斷是否打完 } int main() {scanf("%d",&nm);for (int i=1;i<=nm;i++)for (int j=1;j<=nm;j++)scanf("%d",&a[i][j]);for (int k=1;k<=nm;k++)for (int i=1;i<=nm;i++)for (int j=1;j<=nm;j++)if ((i!=j)&&(j!=k)&&(k!=i)&&(a[i][k]+a[k][j]<a[i][j]))a[i][j]=a[i][k]+a[k][j];//Floyedscanf("%d",&n);for (int i=1;i<=n;i++)scanf("%d",&b[i]);scanf("%d",&m);for (int i=1;i<=m;i++)scanf("%d",&c[i]);l=1;r=10000;while(l<=r){mid=(l+r)/2;//二分答案if (sj(mid)) r=mid-1;else l=mid+1;}printf("%d",l);//輸出return 0; }總結(jié)
以上是生活随笔為你收集整理的【Floyed】【匈牙利算法】导弹(jzoj 1610)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【dfs】GCD与LCM(jzoj 16
- 下一篇: 【离散化】【差分】幻灯片(jzoj 16