最短路問題

內(nèi)容:給定兩個頂點滓彰,在以這兩個點為起點和終點的路徑中,邊的權(quán)值和最小的路徑迂烁。如果把權(quán)值當(dāng)作距離看尼,考慮最短距離的話就很容易理解了。


最短路的例子

單源最短路問題1(Bellman-Ford算法)

單源最短路問題是固定一個起點盟步,求它到其他所有點的最短路的問題藏斩。終點也固定的問題叫做兩點之間最短路問題。但是因為解決單源最短路問題的復(fù)雜度也是一樣的却盘,因此通常當(dāng)作單源最短路問題來求解
記從起點s出發(fā)到頂點i的最短距離為d[i]狰域,則下述等式成立。
d[i]=min{d[j]+(從j到i的邊的權(quán)值)|e=(j,i)∈E}
如果給定的圖是一個DAG(有向無環(huán)圖)就可以按拓撲序給定點編號黄橘,并利用用這條遞推關(guān)系式計算出d北专。但是,如果圖中有圈旬陡,就無法以來這樣的順序進行計算。在這種情況下语婴,記當(dāng)前到頂點i的最短路長度為d[i]描孟,并設(shè)初值d[s]=0,d[i]=INF(足夠大的常數(shù)),再不斷使用這條遞推關(guān)系式更新d的值砰左,就可以算出新的d匿醒。只要圖中不存在負圈,這樣的更新操作就是有限的缠导。結(jié)束之后的d就是所求的最短距離了廉羔。
模板

//從頂點from指向頂點to的權(quán)值為cost的邊
struct edge{
    int from,to,cost;
}; 
edge es[MAX_E];//邊
int d[MAX_V];//最短距離
int V,E;//V是頂點數(shù),E是變數(shù)

//求解從頂點s出發(fā)到所有點的最短距離
void shortest_path(int s){
    for(int i=0;i<V;i++)
        d[i]=INF;
    d[s]=0;
    while(true){
        bool updata=false;
        for(int i=0;i<E;i++){
            edge e=es[i];
            if(d[e.from]!=INF&&d[e.to]>d[e.from]+e.cost){
                d[e.to]=d[e.from]+e.cost;
                update=true;
            }
        }
        if(!update) 
            break;
    }
} 

這個算法叫做Bellman-Ford算法僻造。如果在圖中不存在從s可達的負圈憋他,那么最短路不會經(jīng)過同一個頂點兩次(也就是說孩饼,最多通過|V|-1條邊),while(true)的循環(huán)也最多執(zhí)行|V|-1次竹挡,因此镀娶,復(fù)雜度是O(|V|*|E|)。反之揪罕,如果存在從s可達的負圈梯码,那么在第|V|次循環(huán)中也會更新d的值,因此也可以用這個性質(zhì)來檢查負圈好啰。如果一開始對所有的頂點i轩娶,都把d[i]初始化為0,那么可以檢查出所有的負圈框往。

//如果返回true則存在負圈
bool find_negative_loop(){
    memset(d,0,sizeof(d));
    for(int i=0;i<V;i++){
        for(int j=0;j<E;j++){
            edge e=es[j];
            if(d[e.to]>d[e.from]+e.cost){
                d[e.to]=d[e.from]+e.cost;
                
                //如果第n次仍然更新了鳄抒,則存在負圈
                if(i==V-1)
                    return true; 
            }
        }
    }
    return false;
} 

?

單源最短路問題2(Dijkstra算法)//迪杰克斯拉

讓我們考慮沒有負邊的情況。在Bellman-Ford算法中搅窿,如果d[i]還不是最短距離的話嘁酿,那么即使進行d[j]=d[i]+(從i到j(luò)的邊的權(quán)值的更新),d[j]也不會變成最短距離男应。而且?d[i]沒有變化闹司,每一次循環(huán)也要檢查一遍從i出發(fā)的所有邊。這顯然是很浪費時間的沐飘。因此可以對算法做如下修改游桩。

  • 找到最短距離和已經(jīng)確定的頂點,從它出發(fā)更新相鄰頂點的最短距離耐朴。
  • 此后不需要再關(guān)心1中的“最短距離已經(jīng)確定的頂點”
    上面提到的“最短距離已經(jīng)確定的頂點”要怎么得到是問題的關(guān)鍵借卧。在最開始時,只有起點和最短距離是確定的筛峭。而在尚未使用過的頂點中铐刘,距離d[i]最小的頂點就是最短距離已經(jīng)確定的頂點。這是因為由于不存在負邊影晓,所以d[i]不會在之后的更新中變小镰吵。這個算法叫做Dijkstra算法。


int cost[MAX_V][MAX_V];//cost[u][v]表示邊e=(u挂签,v)的權(quán)值(不存在邊是設(shè)為INF) 
int d[MAX_V];//頂點s出發(fā)的最短距離 
bool used[MAX_V];//已經(jīng)使用過的圖
int V;//頂點數(shù)

//求從起點s出發(fā)到各個頂點的最短距離
void dijkstra(int s){
    fill(d,d+V,INF);
    fill(used,used+V,false);
    d[s]=0;
    
    while(true){
        int v=-1;
        //從尚未使用過的頂點中選擇一個距離最小的頂點
        for(int u=0;u<V;u++){
            if(!used[u]&&(v==-1||d[u]<d[v]))
                v=u;
        }
        if(v==-1)
            break;
        used[v]=true;
        for(int u=0;u<V;u++){
            d[u]=min(d[u],d[v]+cost[v][u]);
        } 
    }
} 

使用鄰接矩陣實現(xiàn)的Dijkstra算法的復(fù)雜度是O(|V|2)疤祭。使用鄰接表的話,更新最短距離只需要訪問每一條邊即可饵婆,因此最終復(fù)雜度還是O(|V|2)勺馆。在|E|比較小時,大部分的時間花在了查找下一個使用的頂點上,因此需要使用合適的數(shù)據(jù)結(jié)構(gòu)對其進行優(yōu)化草穆。
需要優(yōu)化的是數(shù)值插入(更新)和取出最小值的兩個操作灌灾,因此使用堆就可以了。把每個頂點當(dāng)前的最短距離用堆維護续挟,在更新最短距離時紧卒,把對應(yīng)的元素往根的方向移動以滿足堆的性質(zhì),而每次從堆中取出的最小值就是下一次要使用的頂點诗祸。這樣堆中元素共有O(|V|)個跑芳,更新和取出數(shù)值的操作有O(|E|)次,因此整個算法的復(fù)雜度是O(|E|log|V|)
下面是使用STL的priority_queue實現(xiàn)直颅。在每次更新時網(wǎng)堆里插入當(dāng)前最短距離和頂點的值對博个。插入的次數(shù)是O(|E|)次,因此元素也是O(|E|)個功偿。當(dāng)取出的最小值不是最短距離的話盆佣,就丟棄這個值。這樣整個算法也可以在同樣的復(fù)雜度內(nèi)完成械荷。

struct edge{
    int to,cost;
};
typedef pair<int,int> P;//first是最短距離共耍,second是頂點的編號

int V;
vector<edge> G[MAX_V];
int d[MAX_V];

void dijkstra(int s){
    //通過greater<P>參數(shù),堆參照first從小到大的順序取出值
    priority_queue<P,vector<P>,greater<P> > que;
    fill(d,d+V,INF);
    d[s]=0;
    que.push(P(0,s));
    
    while(!que.empty()){
        P p=que.top();
        que.pop();
        int v=p.second;
        id(d[v]<p.first)
            continue;
        for(int i=0;i<G[V].size();i++){
            edge e=G[v][i];
            if(d[e.to]>d[v]+e.cost){
                d[e.to]=d[v]+e.cost;
                que.push(P(d[e.to],e.to));
            }
        } 
    } 
} 

?

任意兩點間的最短路問題(Floyd-Warshall算法)

求解所有兩點間的最短路問題叫做任意兩點間的最短路問題吨瞎。讓我們試著用DP求解任意兩點間的最短路問題痹兜。只是用頂點
0 ~ k和i,j的情況下颤诀,記i到j(luò)的最短路長度為d[k+1][i][j]字旭,當(dāng)k=-1時,認為只使用i和j崖叫,所以d[0][i][j]=cost[i][j]遗淳。接下來讓我們把只使用頂點0k的問題歸約到只使用0k-1 的問題上。
只使用0~k時心傀,我們分i到j(luò)的最短路正好經(jīng)過頂點k一次和完全不經(jīng)過頂點k兩種情況來討論屈暗。不經(jīng)過頂點k的情況下,d[k][i][j]=d[k-1][i][j]脂男。通過頂點k的情況下养叛,d[k][i][j]=d[k-1][i][k]+d[k-1][k][j]。合起來就得到了d[k][i][j]=min(d[k-1][i][j],d[k-1][i][k]+d[k-1][k][j])這個DP也可以使用同一個數(shù)組疆液,不斷進行d[i][j]=min(d[i][j],d[i][k]+d[k][j])的更新來實現(xiàn)。
這個算法叫做Floyed-Warshall算法陕贮,可以在O(|V^3|)時間里求得所有兩點間的最短路長度堕油。Floyd-Warshall算法和Bellman-Ford算法一樣,可以處理邊時負數(shù)的情況。而判斷圖中是否有負圈掉缺,只需要檢查是否存在d[i][i]是負數(shù)的頂點i就可以了卜录。

int d[MAX_V][MAX_V];//d[u][v]表示邊e=(u,v)的權(quán)值(不存在時設(shè)為INF,不過d[i][i]=0)
int V;//頂點數(shù)

void warshall_floyd(){
    for(int k=0;k<V;k++)
        for(int i=0;i<V;i++)
            for(int j=0;j<V;j++)
                d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
} 

這樣通過三重循環(huán)非常簡單地就可以求出所有兩點間的最短路長度。由于實現(xiàn)起來非常簡單眶明,如果復(fù)雜度在可以承受的范圍之內(nèi)艰毒,單源最短路也可以使用Floy-Warshall算法進行求解
?

路徑還原

截至目前,我們都只是在求解最短距離搜囱。雖然許多問題只需輸出最短距離就可以了丑瞧,但是也有問題需要求解最短路的路徑。我們以Dijkstra算法為例蜀肘,試著來求解最短路徑绊汹。在求解最短距離時,滿足d[j]=d[k]+cost[k][j]的頂點k扮宠,就是在最短路上頂點j的前趨節(jié)點西乖,因此通過不斷尋找前趨節(jié)點就可以恢復(fù)出最短路,時間復(fù)雜度時O(|E|)坛增。
此外获雕,如果用prev[j]來記錄最短路上頂點j的前趨,那么就可以在O(|V|)的時間內(nèi)完成最短路的回復(fù)收捣,在d[j]被d[j]=d[k]+cost[k][j]更新時届案,修改prev[j]=k;這樣就可以求得prev數(shù)組。在計算從s出發(fā)到j(luò)的最短路時坏晦,通過prev[j]就可以知道頂點j的前趨萝玷,因此不斷把j替換成prev[j]直到j(luò)=s為止就可以了。Bellman-Ford算法和Floyd-Warshall算法都可以用類似的方法進行最短路的還原昆婿。

int prev[MAX_V];//最短路上的前趨頂點

//求從起點s出發(fā)到各個頂點的最短距離
void dijkstra(int s){
    fill(d,d+V,INF);
    fill(used,used+V,false);
    fill(prev,prev+V,-1);
    d[s]=0;
    
    while(true){
        int v=-1;
        for(int u=0;u<V;u++){
            if(!used[u]&&(v==-1||d[u]<d[v]))
                v=u;
        }
        
        if(v==-1)
            break;
        used[v]=true;
        for(int u=0;u<V;u++){
            if(d[u]>d[v]+cost[v][u]){
                d[u]=d[v]+cost[v][u];
                prev[u]=v;
            }
        }
    }
}

//到頂點t的最短路
vector<int> get_path(int t){
    vector<int> path;
    for(;t!=-1;t=prev[t])
        path.push_back(t);//不斷沿著prev[t]走直到t=s
        //這樣得到的就是按照t到s的順序球碉,所以需要翻轉(zhuǎn) 
    reverse(path.begin(),path.end());
    return path; 
} 

?

Emergency

練手題

hhh這道題笑shi我了,明明PAT AC的分數(shù)是25分仓蛆,我還以為我的代碼只有25分//傻了
這道題涉及的不僅僅是每條路徑的值睁冬,還有每座城市都有一個權(quán)值(點權(quán)),還有相關(guān)的最短路的路徑有多少條看疙,將c1到每個城市的相同的路徑計算有多少條豆拨。

#include <iostream>
#include <cstdio>
using namespace std;
const int inf=99999999;
int n,m,c1,c2;
int e[510][510],weight[510],dis[510],num[510],w[510];
bool visit[510];

void dijkstra(){
    fill(visit,visit+510,false);
    fill(dis,dis+510,inf);
    dis[c1]=0;
    w[c1]=weight[c1];
    num[c1]=1;
    while(true){
        int v=-1;
        int minn=inf;
        for(int u=0;u<n;u++){
            if(!visit[u]&&dis[u]<minn){
                v=u;
                minn=dis[u];
            }
        }
        if(v==-1)
            break;
        visit[v]=true;
        for(int u=0;u<n;u++){
            if(!visit[u]&&e[v][u]!=inf){
                if(dis[v]+e[v][u]<dis[u]){
                    dis[u]=dis[v]+e[v][u];
                    num[u]=num[v];
                    w[u]=w[v]+weight[u];
                }else if(dis[v]+e[v][u]==dis[u]){
                    num[u]=num[v]+num[u];
                    if(w[v]+weight[u]>w[u])
                        w[u]=w[v]+weight[u];
                }
            }
        }
    }
    printf("%d %d",num[c2],w[c2]);
}


int main()
{
    //freopen("data","r",stdin);
    scanf("%d%d%d%d",&n,&m,&c1,&c2);
    for(int i=0;i<n;i++)
        cin>>weight[i];
    fill(e[0],e[0]+510*510,inf);

    int a,b,c;
    for(int i=0;i<m;i++){
        cin>>a>>b>>c;
        e[a][b]=e[b][a]=c;
    }
    dijkstra();
    return 0;
}

?

Travel Plan

路徑還原
#include <iostream>
#include <algorithm>
using namespace std;
int n, m, s, D;
int e[501][501],cost[501][501],d[501],c[501];
bool visit[501];
const int inf=99999999;
int pre[501];

void dijkstra(){
    fill(d,d+501,inf);//記錄e 
    fill(c,c+501,inf);//記錄cost 
    fill(visit,visit+501,false);
    d[s]=0;
    c[s]=0;
    while(true){
        int v=-1;
        int minn=inf;
        for(int u=0;u<n;u++){
            if(!visit[u]&&d[u]<minn){
                minn=d[u];
                v=u;
            }
        }
        if(v==-1)
            break;
        visit[v]=true;
        for(int u=0;u<n;u++){
            if(!visit[u]&&e[v][u]!=inf){
                if(d[v]+e[v][u]<d[u]){
                    d[u]=d[v]+e[v][u];
                    c[u]=c[v]+cost[v][u];
                    pre[u]=v;
                }else if(d[u]==d[v]+e[v][u]&&c[u]>c[v]+cost[v][u]){
                    c[u]=c[v]+cost[v][u];
                    pre[u]=v;
                }
            }
        }
    }
}
void dfs(int u){
    if(u==s)
        return;
    dfs(pre[u]);
    cout<<u<<" ";
}

int main(){
//  freopen("data","r",stdin);
    cin>>n>>m>>s>>D;
    fill(e[0],e[0]+501*501,inf);
    fill(cost[0],cost[0]+501,inf);
    int a,b,w,g;
    for(int i=0;i<m;i++){
        cin>>a>>b>>w>>g;
        e[a][b]=e[b][a]=w;
        cost[a][b]=cost[b][a]=g;
    }
    dijkstra();
    cout<<s<<" ";
    dfs(D);
    cout<<d[D]<<" "<<c[D]<<endl;

    return 0;
}

?

All Roads Lead to Rome

多條件
#include<stdio.h>
#include<map>
#include<string>
#include<string.h>
#include<stack>
using namespace std;
#define MAX 210
int INF = 1000000;
int happy[210];
int visit[MAX];
int e[MAX][MAX];
int d[MAX];
int h[MAX];
int num[MAX];
int pre[MAX];
int count[MAX],n;

void dijkstra(int begin)
{
    d[begin] = 0;
    h[begin] = happy[begin];
    num[begin] = 1;
    count[begin] = 0;
    while(true)
    {
        int v = -1;
        int minn = INF;
        for(int u = 0 ;u <n ;u++)
        {
            if(!visit[u] && d[u] < minn)
            {
                v = u;
                minn= d[u];
            }
        }

        if(v == -1) return ;
        visit[v] = true;
        for(int u = 0 ;u <n ;u++)
        {
            if(!visit[u] && e[v][u]!=INF)
            {
                if(d[v]+e[v][u]<d[u])
                {
                    d[u] = d[v]+e[v][u];
                    num[u] = num[v];
                    h[u] = h[v] + happy[u];
                    pre[u] = v;
                    count[u] = count[v] +1;
                }
                else if(d[v]+e[v][u]==d[u])
                {
                    num[u] = num[u] + num[v];

                    if(h[u] < h[v] + happy[u])
                    {
                        h[u] = h[v] + happy[u];
                        count[u] = count[v] +1;
                        pre[u] = v;
                    }
                    else if( h[u] == h[v] + happy[u] && (double)(h[v] + happy[u])/(count[v]+1) > (double)h[u]/count[u])
                    {
                        count[u] = count[v] +1;
                        pre[u] = v;
                    }
                }
            }
        }
    }

}

int main()
{
    int i,j,K,Happy,ROM;
    char begin[4],tem[4];
    scanf("%d%d%s",&n,&K,begin);
    map<string,int> mm;
    map<int,string> mm2;
    mm[begin] = 0;
    mm2[0] = begin ;
    happy[mm[begin]] = 0;
    for(i = 1 ; i < n ;i++)
    {
        scanf("%s%d",tem,&Happy);
        if(strcmp("ROM",tem)==0) ROM = i;//這里可以不要
        mm[tem] = i;
        mm2[i] = tem;
        happy[i] = Happy;
    }

    char x[4],y[4];
    fill(e[0],e[0]+MAX*MAX,INF);
    fill(d,d+MAX,INF);
    fill(h,h+MAX,INF);
    fill(pre,pre+MAX,-1);
    fill(count,count+MAX,0);
    for(i = 0 ; i < K ;i++)
    {
        scanf("%s%s",x,y);
        scanf("%d",&e[mm[x]][mm[y]]);
        e[mm[y]][mm[x]] = e[mm[x]][mm[y]];
    }

    dijkstra( mm[begin]);

    printf("%d %d %d %d\n",num[mm["ROM"]],d[mm["ROM"]],h[mm["ROM"]],h[mm["ROM"]]/count[mm["ROM"]]);

    stack<int> ss;
    i= mm["ROM"];
    while(i != -1)
    {
        ss.push(i);
        i = pre[i];
    }
    int fir = 1;
    while(!ss.empty())
    {
        if(fir == 1)
        {
            fir = 0;
            printf("%s",mm2[ss.top()].c_str());
        }
        else printf("->%s",mm2[ss.top()].c_str());
        ss.pop();
    }

    printf("\n");

    return 0;
}

?

HDU Today

STL map+Dijkstra
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
using namespace std;
#define MAX 2100 
int INF = 99999999,n;
int e[MAX][MAX],d[MAX];
bool visit[MAX];
map <string,int>mm;
string a,b,s,aend;
int c,k=1;

void dijkstra(){
    fill(d,d+k+1,INF);
    fill(visit,visit+k,false);
    d[1]=0;
    while(true){
        int v=-1;
        for(int u=1;u<=k;u++){//這里千萬不能是n 
            if(!visit[u]&&(v==-1||d[u]<d[v])){
                v=u;
            }
        }
        if(v==-1){
            break;
        }
        visit[v]=true;
        for(int u=1;u<=k;u++){
            if(!visit[u]&&e[v][u]!=INF){
                if(d[u]>d[v]+e[v][u]){
                    d[u]=d[v]+e[v][u];
                }
            }
        }
    }
}

int main(){
    while(cin>>n&&n!=-1){
        mm.clear();
        cin>>s>>aend;
        //用map映射給站名標記,起始站為1能庆,終點站為2
        //怪不得之前的代碼總是bug
        k=1;//這里忘記初始化施禾,every time 卡了那么久,原來是在這里
        mm[s]=k++;
        mm[aend]=k++;
        //初始化e 
        for(int i=0;i<155;i++){
            for(int j=0;j<155;j++){
                if(i==j)
                    e[i][j]=0;
                else
                    e[i][j]=INF;
            }
        }
        for(int i=1;i<=n;i++){
            cin>>a>>b>>c;
            if(!mm[a])
                mm[a]=k++;
            if(!mm[b])
                mm[b]=k++;
            if(c<e[mm[a]][mm[b]])
                e[mm[a]][mm[b]]=e[mm[b]][mm[a]]=c;
        }   
        if(s==aend)
            cout<<"0"<<endl;
        else{
            dijkstra();
            if(d[2]==INF)
                cout<<"-1"<<endl;
            else
                cout<<d[2]<<endl;
        }       
    }
    return 0;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末搁胆,一起剝皮案震驚了整個濱河市弥搞,隨后出現(xiàn)的幾起案子邮绿,更是在濱河造成了極大的恐慌,老刑警劉巖攀例,帶你破解...
    沈念sama閱讀 223,126評論 6 520
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件船逮,死亡現(xiàn)場離奇詭異,居然都是意外死亡粤铭,警方通過查閱死者的電腦和手機挖胃,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,421評論 3 400
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來梆惯,“玉大人酱鸭,你說我怎么就攤上這事〖哟” “怎么了凛辣?”我有些...
    開封第一講書人閱讀 169,941評論 0 366
  • 文/不壞的土叔 我叫張陵,是天一觀的道長职烧。 經(jīng)常有香客問我扁誓,道長,這世上最難降的妖魔是什么蚀之? 我笑而不...
    開封第一講書人閱讀 60,294評論 1 300
  • 正文 為了忘掉前任蝗敢,我火速辦了婚禮,結(jié)果婚禮上足删,老公的妹妹穿的比我還像新娘寿谴。我一直安慰自己,他們只是感情好失受,可當(dāng)我...
    茶點故事閱讀 69,295評論 6 398
  • 文/花漫 我一把揭開白布讶泰。 她就那樣靜靜地躺著,像睡著了一般拂到。 火紅的嫁衣襯著肌膚如雪痪署。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,874評論 1 314
  • 那天兄旬,我揣著相機與錄音狼犯,去河邊找鬼。 笑死领铐,一個胖子當(dāng)著我的面吹牛悯森,可吹牛的內(nèi)容都是我干的骇笔。 我是一名探鬼主播钓瞭,決...
    沈念sama閱讀 41,285評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼延塑!你這毒婦竟也來了音诈?” 一聲冷哼從身側(cè)響起幻碱,我...
    開封第一講書人閱讀 40,249評論 0 277
  • 序言:老撾萬榮一對情侶失蹤续膳,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后收班,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,760評論 1 321
  • 正文 獨居荒郊野嶺守林人離奇死亡谒兄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,840評論 3 343
  • 正文 我和宋清朗相戀三年摔桦,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片承疲。...
    茶點故事閱讀 40,973評論 1 354
  • 序言:一個原本活蹦亂跳的男人離奇死亡邻耕,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出燕鸽,到底是詐尸還是另有隱情兄世,我是刑警寧澤,帶...
    沈念sama閱讀 36,631評論 5 351
  • 正文 年R本政府宣布啊研,位于F島的核電站御滩,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏党远。R本人自食惡果不足惜削解,卻給世界環(huán)境...
    茶點故事閱讀 42,315評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望沟娱。 院中可真熱鬧氛驮,春花似錦、人聲如沸济似。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,797評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽砰蠢。三九已至蓖扑,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間娩脾,已是汗流浹背赵誓。 一陣腳步聲響...
    開封第一講書人閱讀 33,926評論 1 275
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留柿赊,地道東北人俩功。 一個月前我還...
    沈念sama閱讀 49,431評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像碰声,于是被迫代替她去往敵國和親诡蜓。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,982評論 2 361

推薦閱讀更多精彩內(nèi)容